目标
- 学习对图像应用不同的几何变换,如平移,旋转,仿射变换等。
- 你会看到这些函数:cv.getPerspectiveTransform
转换
OpenCV提供了两个转换函数,cv.warpAffine和cv.warpPerspective,使用这两个函数你可以进行实现所有类型的转换。cv.warpAffine采用2×3变换矩阵,而cv.warpPerspective采用3×3变换矩阵作为输入。
扩展缩放
扩展缩放只是调整图像大小。为此,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('lena.jpg')
#输入,输出,X缩放因子,Y缩放因子,插值方法
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)
cv.imshow('src',img)
cv.imshow('res',res)
cv.waitKey(0)
平移
平移就是将对象转换一个位置。如果要沿着(x,y)方向的移动,移动的距离为(tx,t y),则可以按如下方式创建变换矩阵
使用Numpy数组构建这个矩阵(数据类型是np.float32),并将它传递给cv.warpAffine()函数。下面的例子被移动了(100,50)个像素:
程序:
import cv2 as cv
img = cv.imread('lena.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()
警告
cv.warpAffine()函数的第三个参数是输出图像的大小,它应该是图像的(width,height)的形式。请记住width =列数,height =行数。
结果:
旋转
对一个图像旋转角度 θ, 需要使用到下面形式的旋转矩阵。
为了找到这个变换矩阵,OpenCV提供了一个函数cv.getRotationMatrix2D。下面的这个例子是对图像旋转90度。
程序:
import numpy as np
import cv2 as cv
img = cv.imread('lena.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.imshow('img',dst)
cv.waitKey(0)
cv.destroyAllWindows()
结果:
仿射变换
在仿射变换中,原始图像中的所有平行线在输出图像中仍然是平行的。为了找到变换矩阵,我们需要输入图像中的三个点以及它们在输出图像中的相应位置。然后cv.getAffineTransform将创建一个2x3矩阵,并将其传递给cv.warpAffine。
程序:
import numpy as np
import cv2 as cv
from matplotlib import pyplot as plt
img = cv.imread('lena.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 = cv.getAffineTransform(pts1,pts2)
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转换矩阵。
程序:
import numpy as np
from matplotlib import pyplot as plt
img = cv.imread('lena.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 = cv.getPerspectiveTransform(pts1,pts2)
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')
plt.show()
结果: