OpenCV 提供了两个转换函数,cv.warpAffine 和 cv.warpPerspective,您可以使用它们执行各种转换。 cv.warpAffine 采用 2x3 变换矩阵,而 cv.warpPerspective 采用 3x3 变换矩阵作为输入。
缩放只是调整图像的大小。为此,OpenCV 带有一个函数 cv.resize()。可以手动指定图像的大小,也可以指定比例因子。使用不同的插值方法。首选的插值方法是用于缩小的 cv.INTER_AREA 和用于放大的 cv.INTER_CUBIC(慢)和 cv.INTER_LINEAR。默认情况下,插值方法 cv.INTER_LINEAR 用于所有调整大小的目的。您可以使用以下任一方法调整输入图像的大小:
import numpy as np
import cv2 as cv
img = cv.imread('messi5.jpg')
res = cv.resize(img,None,fx=2, fy=2, interpolation = cv.INTER_CUBIC)
#OR
height, width = img.shape[:2]
res = cv.resize(img,(2*width, 2*height), interpolation = cv.INTER_CUBIC)
#像素放大为原来长宽的两倍
平移是物体位置的移动。如果您知道 (x,y) 方向的偏移并让它成为 (tx,ty),您可以创建变换矩阵 M,如下所示:
您可以将其放入 np.float32 类型的 Numpy 数组中,并将其传递给 cv.warpAffine() 函数。有关 (100,50) 的移位,请参见以下示例:
import numpy as np
import cv2 as cv
img = cv.imread('messi5.jpg',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()
#这里我的理解是tx是x轴移动距离,ty是y轴移动距离
cv.warpAffine() 函数的第三个参数是输出图像的大小,应该是**(width, height)** 的形式。请记住宽度 = 列数,高度 = 行数。
图像旋转角度 θ 是通过以下形式的变换矩阵实现的:
但是 OpenCV 提供了旋转中心可调的缩放旋转,这样你就可以在任何你喜欢的位置旋转。修改后的变换矩阵由下式给出:
其中
为了找到这个变换矩阵,OpenCV 提供了一个函数,cv.getRotationMatrix2D。查看下面的示例,该示例将图像相对于中心旋转 90 度而不进行任何缩放。
img = cv.imread('messi5.jpg',0)
rows,cols = img.shape
# cols-1 and rows-1 are the coordinate limits.
M = cv.getRotationMatrix2D(((cols-1)/2.0,(rows-1)/2.0),90,1)
#旋转中心,旋转角度,缩放尺度
dst = cv.warpAffine(img,M,(cols,rows))
在仿射变换中,原始图像中的所有平行线在输出图像中仍然是平行的。为了找到变换矩阵,我们需要输入图像中的三个点及其在输出图像中的对应位置。然后 cv.getAffineTransform 将创建一个 2x3 矩阵,该矩阵将传递给 cv.warpAffine。
检查下面的示例,并查看我选择的点(以绿色标记):
img = cv.imread('drawing.png')
rows,cols,ch = img.shape
pts1 = np.float32([[50,50],[200,50],[50,200]])
#点坐标1
pts2 = np.float32([[10,100],[200,50],[100,250]])
#点坐标2
M = cv.getAffineTransform(pts1,pts2)
#参数1:原始图像中三个点的坐标 参数2:变换后三个点的坐标, M 是根据三个对应点求出的仿射变换矩阵
dst = cv.warpAffine(img,M,(cols,rows))
plt.subplot(121),plt.imshow(img),plt.title('Input')
plt.subplot(122),plt.imshow(dst),plt.title('Output')
plt.show()
对于透视变换,您需要一个 3x3 变换矩阵。即使在转换之后,直线仍将保持笔直。要找到这个变换矩阵,您需要输入图像上的 4 个点和输出图像上的对应点。这4个点中,有3个不应该共线。然后可以通过函数 cv.getPerspectiveTransform 找到变换矩阵。然后将 cv.warpPerspective 与这个 3x3 变换矩阵一起应用。
img = cv.imread('sudoku.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 = cv.getPerspectiveTransform(pts1,pts2)
#这个和上面一样不过要求是4个点
dst = cv.warpPerspective(img,M,(300,300))
plt.subplot(121),plt.imshow(img),plt.title('Input')
plt.subplot(122),plt.imshow(dst),plt.title('Output')