应用OpenCV进行图像旋转和平移

Posted 卓晴

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了应用OpenCV进行图像旋转和平移相关的知识,希望对你有一定的参考价值。

简 介: 本文中,你了解了了如何通过OpenCV完成对于图像的旋转和平移。我们首先通过 getRotationMatrix2D() 获取2D旋转矩阵,然后完成了对于图像的旋转。具体是通过warpAffine() 将旋转拒转施加在图像上完成对图像绕着中心旋转所需的角度。接着通过明确定义了转换矩阵,包含有想要图像沿着xy轴移动的信息。同样利用warpAffine()函数对图像进行变换。旋转和平移图像是我们学习利用OpenCV完成对图像进行其它变化的良好的基础。鼓励你在此基础上测试其它的输入查看一下变化的效果。

关键词 图像旋转图像平移

前 言 目 录
Contents
图像的基本变换 图像旋转 图像平移 转换总结

 

§00   言

本文是对 Image Rotation and Translation Using OpenCV 中介绍的关于OpenCV进行图像旋转和平移内容进行总结。

  自从手机内的内置的APP都考可以让你随心所欲对你拍摄的图像进行剪裁、旋转的时候,对于图像进行编辑变得越来越流行。

  本文中,我们将会探讨这些图像班级的技术。特别对于:

  • 如何旋转图像;
  • 如何平移图像的内容;

0.1 图像的基本变换

  在图像编辑中,对于图像进行旋转和平移是最基本的操作,他们都归于“仿射变换”(Affine Tranformations)这一大类。在学习更复杂的变换之前,对于基本的旋转和平移需要掌握,这些都可以通过OpenCV来实现。

  下面这张图将会在后面的软件测试中使用。

▲ 图1.1 用于后面实验的图片样例

  上面这张图我们后面将会使用到。

  在开始前可以先看看下面的代码,他们通过OpenCV执行图像的旋转。在后面我们将会对于代码的每一行伴随着对于图片的转换进行解释。最后,我们就会对下面的代码有了充分的理解。

  • Python
import cv2

# Reading the image
image = cv2.imread('image.jpg')

# dividing height and width by 2 to get the center of the image
height, width = image.shape[:2]
# get the center coordinates of the image to create the 2D rotation matrix
center = (width/2, height/2)

# using cv2.getRotationMatrix2D() to get the rotation matrix
rotate_matrix = cv2.getRotationMatrix2D(center=center, angle=45, scale=1)

# rotate the image using cv2.warpAffine
rotated_image = cv2.warpAffine(src=image, M=rotate_matrix, dsize=(width, height))

cv2.imshow('Original image', image)
cv2.imshow('Rotated image', rotated_image)
# wait indefinitely, press any key on keyboard to exit
cv2.waitKey(0)
# save the rotated image to disk
cv2.imwrite('rotated_image.jpg', rotated_image)
  • C++
#include <iostream>
#include<opencv2/opencv.hpp>
using namespace cv;

int main(int, char**) 

    Mat image = imread("image.jpg");
	  imshow("image", image);
	  waitKey(0);
	  double angle = 45;

	  // get the center coordinates of the image to create the 2D rotation matrix
	  Point2f center((image.cols - 1) / 2.0, (image.rows - 1) / 2.0);
	  // using getRotationMatrix2D() to get the rotation matrix
	  Mat rotation_matix = getRotationMatrix2D(center, angle, 1.0);

	  // we will save the resulting image in rotated_image matrix
	  Mat rotated_image;
	  // rotate the image using warpAffine
	  warpAffine(image, rotated_image, rotation_matix, image.size());
	  imshow("Rotated image", rotated_image);
    // wait indefinitely, press any key on keyboard to exit
	  waitKey(0);
	  // save the rotated image to disk
	  imwrite("rotated_im.jpg", rotated_image);

	  return 0;

 

§01 像旋转


  以通过定出 一个旋转矩阵 M M M 完成对图像 任意角度 θ \\theta θ 的旋转。这个旋转矩阵通常具有如下形式:

M = [ cos ⁡ θ − sin ⁡ θ sin ⁡ θ cos ⁡ θ ] M = \\beginbmatrix \\beginmatrix \\cos \\theta & - \\sin \\theta \\\\\\sin \\theta & \\cos \\theta \\\\\\endmatrix \\endbmatrix M=[cosθsinθsinθcosθ]

  OpenCV可以定义图像的旋转中心点,以及比例因子来缩放图像,在这些因素作用下,这个转换矩阵的形式变成如下的形式:

[ α π ( 1 − α ) ⋅ c x − β ⋅ c y − β α β ⋅ c x + ( 1 − α ) ⋅ c y ] \\beginbmatrix \\beginmatrix \\alpha & \\pi & \\left( 1 - \\alpha \\right) \\cdot c_x - \\beta \\cdot c_y \\\\ - \\beta & \\alpha & \\beta \\cdot c_x + \\left( 1 - \\alpha \\right) \\cdot c_y \\\\\\endmatrix \\endbmatrix [αβπα(1α)cxβcyβcx+(1α)cy]

  在上面的矩阵中: α = s c a l e ⋅ cos ⁡ θ \\alpha = scale \\cdot \\cos \\theta α=scalecosθ β = s c a l e ⋅ sin ⁡ θ \\beta = scale \\cdot \\sin \\theta β=scalesinθ

  其中 c x , c y c_x ,c_y cx,cy 就是图片的旋转中心点坐标。

  OpenCV提供getRotationMatrix2D() 函数来创建上述转换矩阵。

  下面就是创建2D旋转矩阵的函数调用方式:

getRotationMatrix2D(center, angle, scale)

  函数 getRotationMatrix2D() 有以下三个输入变量:

  • center: the center of rotation for the input image
  • angle: the angle of rotation in degrees
  • cale: an isotropic scale factor which scales the image up or down according to the value provided

  通过三个步骤完成旋转:
  1. 首先,你需要得到旋转的中心,也就是你用于旋转图像所围绕的中心点;
  2. 接着,创建 2D-旋转拒转。 OpenCV提供了上面讨论的 getRotationMatrix2D() 函数。
  3. 最后,使用前面你创建的旋转矩阵对图像进行仿射变换。利用 OpenCV 中的warpAffine() 函数完成。

  函数 warpAffine() 对图像施加仿射变换。在仿射变换后,所有的原始图像中的平行线在变换后仍然是平行线。

  函数 warpAffine() 的复杂调用语法在下面给出:

  • rc: the source mage
  • M: the transformation matrix
  • dsize: size of the output image
  • dst: the output image
  • flags: combination of interpolation methods such as INTER_LINEAR or INTER_NEAREST
  • borderMode: the pixel extrapolation method
  • borderValue: the value to be used in case of a constant border, has a default value of 0

  请注意:在此你可以学习OpenCV 仿射变换更多的内容。

  好了,现在你已经了解了相关的代码和函数,下面采用一个具体的OpenCV例子测试一下。首先你需要吧OpenCV的库和图片导入。

  • Python
import cv2

# Reading the image
image = cv2.imread('image.jpg')
  • C++
#include "opencv2/opencv.hpp"
using namespace cv;

# Reading the image
Mat image = imread("image.jpg");

  接着,计算旋转点,在这个例子中就是图像的中心。所以只要简单的吧图像的宽和高除以二就可以了。

  • Python
# Dividing height and width by 2 to get the center of the image
height, width = image.shape[:2]
center = (width/2, height/2)
  • C++
// get the center coordinates of the image to create the 2D rotation matrix
Point2f center((image.cols - 1) / 2.0, (image.rows - 1) / 2.0);

  一旦你获得图像旋转中心,就可以计算出旋转矩阵。利用函数 getRotationMatrix2D() 完成,看下面所示,这个函数需要的输入包括:

  • 旋转中心点;
  • 旋转角度,单位°(注意,不是弧度),正值表示逆时针旋转,负值表示顺时针旋转;
  • 各向同性的图片缩放比例因子。这个可以使一个浮点数字。比如,1.0表示保持输出图像与输入图像的尺寸一致。 2.0表示输出图像的尺寸比输入图像大了一倍。

  函数返回一个2D-旋转拒转,下面就是用该矩阵对图像进行旋转。

  • Python
# the above center is the center of rotation axis
# use cv2.getRotationMatrix2D() to get the rotation matrix
rotate_matrix = cv2.getRotationMatrix2D(center=center, angle=45, scale=1)
  • C++
// create the rotation matrix using the image center
Mat rotation_matix = getRotationMatrix2D(center, angle=45, 1.0);

  现在,通过函数 warpAffine()将旋转拒转作用在图像上,这个函数需要三个输入:
  1. 原始图像;
  2. 旋转拒转;
  3. 输出图像的尺寸;

  旋转结果存储在 rotated_image中,下面我们会展示出来。

  • Python
# Rotate the image using cv2.warpAffine
rotated_image = cv2.warpAffine(src=image, M=rotate_matrix, dsize=(width, height))
  • C++
// we will save the resulting image in rotated_image matrix
Mat rotated_image;
// apply affine transformation to the original image using the 2D rotation matrix
warpAffine(image, rotated_image, rotation_matix, image.size());

  下面我们现实旋转后的图像,仍然使用 imshow() 函数。

  • Python
# visualize the original and the rotated image
cv2.imshow('Original image', image)
cv2.imshow('Rotated image', rotated_image)
# wait indefinitely, press any key on keyboard to exit
cv2.waitKey(0)
# write the output, the rotated image to disk
cv2.imwrite('rotated_image.jpg', rotated_image)
  • C++
imshow("Rotated image", rotated_image);
waitKey(0);
// save the rotated image to disk
imwrite("rotated_im.jpg", rotated_image);

以上是关于应用OpenCV进行图像旋转和平移的主要内容,如果未能解决你的问题,请参考以下文章

OpenCV新手入门,如何用它平移缩放和旋转图片

opencv 图像平移缩放旋转翻转 图像仿射变换

从 OpenCV 中的旋转矩阵和平移向量中获取旋转轴

OpenCV从仿射矩阵得到旋转量平移量缩放量

OpenCV从仿射矩阵得到旋转量平移量缩放量

opencv 图像变换原理详解 图像平移 图像旋转 图像缩放