开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第 11 天,点击查看活动详情
目标
- 学习将不同的几何变换应用到图像上,如平移、旋转、仿射变换等。
- 函数:
cv.getPerspectiveTransform
变换
OpenCV提供了两个转换函数cv2.warpAffine和cv2.warpPerspective,可以使用它们进行各种转换。cv2.warpAffine采用2x3转换矩阵,而cv2.warpPerspective采用3x3转换矩阵作为输入。
缩放
缩放只是调整图像的大小。为此,OpenCV带有一个函数cv2.resize()。图像的大小可以手动指定,也可以指定缩放比例。也可使用不同的插值方法。首选的插值方法是cv2.INTER_AREA用于缩小,cv2.INTER_CUBIC(慢)和cv2.INTER_LINEAR用于缩放。默认情况下,出使用的插值方法为cv2.INTER_LINEAR。可以使用以下方法调整输入图像的大小:
import cv2
import numpy as np
img = cv2.imread('messi.png')
res = cv2.resize(img, None, fx=2, fy=2, interpolation=cv.INTER_CUBIC)
#或者
height, width = img.shape[:2]
res = cv2.resize(img,(2*width, 2*height), interpolation=cv2.INTER_CUBIC)
平移
平移是物体位置的移动。如果知道在(x,y)方向上的位移,则将其设为(t_x, t_y ),可以创建转换矩阵M ,如下所示:
可以将其放入np.float32类型的Numpy数组中,并将其传递给cv2.warpAffine函数。参见下面偏移为(100, 50)的示例:
import cv2
import numpy as np
img = cv2.imread('messi.png', 0)
rows,cols = img.shape
M = np.float32([[1,0,100],[0,1,50]]) # 方向
dst = cv.warpAffine(img,M,(cols,rows))
cv.imshow('img',dst)
cv.waitKey(0)
cv.destroyAllWindows()
警告
cv2.warpAffine函数的第三个参数是输出图像的大小,其形式应为(width,height)。记住width =列数,height =行数。
旋转
图像旋转角度为θ是通过以下形式的变换矩阵实现的:
但是OpenCV提供了可缩放的旋转以及可调整的旋转中心,因此可以在自己喜欢的任何位置旋转。修改后的变换矩阵为
其中:
为了找到此转换矩阵,OpenCV提供了一个函数cv2.getRotationMatrix2D。请检查以下示例,该示例将图像相对于中心旋转90度而没有任何缩放比例。
img = cv2.imread('messi.png', 0)
rows,cols = img.shape
M = cv2.getRotationMatrix2D(((cols-1)/2.0, (rows-1)/2.0), 90,1) # cols-1 和 rows-1 是坐标限制
dst = cv2.warpAffine(img, M, (cols,rows))
仿射变换
在仿射变换中,原始图像中的所有平行线在输出图像中仍将平行。为了找到变换矩阵,需要输入图像中的三个点及其在输出图像中的对应位置。然后cv2.getAffineTransform将创建一个2x3矩阵,该矩阵将传递给cv2.warpAffine。
查看以下示例,并查看选择的点(以绿色标记):
img = cv2.imread('draw.png')
rows,cols,c = 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))
plt.subplot(121),plt.imshow(img),plt.title('Input')
plt.subplot(122),plt.imshow(dst),plt.title('Output')
查看结果:
透视变换
对于透视变换,需要3x3变换矩阵。即使在转换后,直线也将保持直线。要找到此变换矩阵,需要在输入图像上有4个点,在输出图像上需要相应的点。在这四个点中,其中三个不应共线。然后可以通过函数cv2.getPerspectiveTransform找到变换矩阵。然后将cv2.warpPerspective应用于此3x3转换矩阵。
img = cv2.imread('sudo.png')
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))
plt.subplot(121),plt.imshow(img), plt.title('Input')
plt.subplot(122),plt.imshow(dst), plt.title('Output')
plt.show()