应用OpenCV进行图像旋转和平移
Posted 卓晴
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了应用OpenCV进行图像旋转和平移相关的知识,希望对你有一定的参考价值。
简 介: 本文中,你了解了了如何通过
OpenCV
完成对于图像的旋转和平移。我们首先通过getRotationMatrix2D()
获取2D
旋转矩阵,然后完成了对于图像的旋转。具体是通过warpAffine()
将旋转拒转施加在图像上完成对图像绕着中心旋转所需的角度。接着通过明确定义了转换矩阵,包含有想要图像沿着x
,y
轴移动的信息。同样利用warpAffine()
函数对图像进行变换。旋转和平移图像是我们学习利用OpenCV
完成对图像进行其它变化的良好的基础。鼓励你在此基础上测试其它的输入查看一下变化的效果。
关键词
: 图像旋转,图像平移
§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 α=scale⋅cosθ β = s c a l e ⋅ sin θ \\beta = scale \\cdot \\sin \\theta β=scale⋅sinθ
其中 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进行图像旋转和平移的主要内容,如果未能解决你的问题,请参考以下文章