学习对图像进行各种几个变换,例如移动,旋转,仿射变换等。
OpenCV提供了两个变换函数,cv2.warpAffine和cv2.warpPerspective,使用这两个函数你可以实现所有类型的变换。cv2.warpAffine接收的参数是
2x3 的变换矩阵,而cv2.warpPerspective接收的参数是3x3的变换矩阵
阵。
缩放只是图像的大小调整。cv2.resize()就可以实现这个功能了。可以手动指定图像的尺度,也可以指定缩放因素。我们可以选择使用不同的插值方法。在缩放时推荐使用cv2.INTER_AREA,在扩展时推荐使用cv2.INTER_CUBIC(慢)和cv2.INTER_LINEAR。默认情况下所有改变图像尺寸大小的操作使用的插值方法都是cv2.INTER_LINEAR。你可以使用下面任意一种方法改变图像的尺寸:
#指定缩放因素
res = cv2.resize(img,None,fx=2, fy=2, interpolation = cv2.INTER_CUBIC)
#OR
height, width = img.shape[:2]
#指定图像尺度
res = cv2.resize(img,(2*width, 2*height), interpolation = cv2.INTER_CUBIC)
平移就是将对象换一个位置。如果你要沿(x,y)方向移动,移动的距离是(t_x,t_y),你可以以下面的方式构建移动矩阵:
| 1 0 t_x |
M= | 0 1 t_y |
你可以使用Numpy数组构建这个矩阵(数据类型是 np.float32),然后把它传给函数cv2.warpAffine(),下面的例子移动了(100,50)个像素:
import cv2
import numpy as np
img = cv2.imread('messi5.jpg',0)
rows,cols = img.shape
M = np.float32([[1,0,100],[0,1,50]])
dst = cv2.warpAffine(img,M,(cols,rows))
cv2.imshow('img',dst)
cv2.waitKey(0)
cv2.destroyAllWindows()
警告:
函数 cv2.warpAffine() 的第三个参数的是输出图像的大小,它的格式应该是图像的(宽,高)。
应该记住的是图像的宽对应的是列数,高对应的是行数。
对一个图像旋转角度,需要使用到下面形式的旋转矩阵:
| cos(x) - sin(x) |
M=| sin(x) - cos(x) |
但是OpenCV 允许你在任意地方进行旋转,但是旋转矩阵的形式应该修改为:
| a b (1-a)*center.x - b*center.y |
|-b a b*center.x + (1-a)*center.y |
其中:
a = scale * cos(x),
b = scale * sin(x)
为了构建这个旋转矩阵,OpenCV 提供了一个函数:cv2.getRotationMatrix2D。下面的例子是在不缩放的情况下将图像旋转 90 度:
img=cv2.imread('123.jpg',0)
rows,cols=img.shape
M=cv2.getRotationMatrix2D((cols/2,rows/2),90,1)
dst=cv2.warpAffine(img,M,(cols,rows))
在仿射变换中,原图中所有的平行线在结果图像中同样平行。为了创建这个矩阵我们需要从原图像中找到三个点以及他们在输出图像中的位置。然后 cv2.getAffineTransform 会创建一个 2x3 的矩阵,最后这个矩阵会被传给函数cv2.warpAffine。
来看看下面的例子,以及我选择的点(被标记为绿色的点):
img=cv2.imread('123.jpg')
rows,cols,ch=img.shape
pts1=np.float32([[50,50],[200,50],[50,200]])
pts2=np.float32([[10,100],[200,50],[100,250]])
M=cv2.getAffineTransform(pts1,pts2)
dst=cv2.warpAffine(img,M,(cols,rows))
对于视角变换,我们需要一个 3x3 变换矩阵。在变换前后直线还是直线。要构建这个变换矩阵,你需要在输入图像上找 4 个点,以及他们在输出图像上对应的位置。这四个点中的任意三个都不能共线。这个变换矩阵可以有函数 cv2.getPerspectiveTransform() 构建。然后把这个矩阵传给函数 cv2.warpPerspective。
img=cv2.imread('123.jpg')
rows,cols,ch=img.shape
pts1=np.float32([[56,65],[368,52],[28,387],[389,390]])
pts2=np.float32([[0,0],[300,0],[0,300],[300,300]])
M=cv2.getPerspectiveTransform(pts1,pts2)
dst=cv2.warpPerspective(img,M,(300,300))