OpenCV-Python Tutorials官方英文教程
GitHub:中文翻译
如果对你有帮助, 请在GitHub上Star该项目, 转载请注明出处。
cv.getPerspectiveTransform
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)要位移的距离,让它为变为( t x t_x tx, t y t_y ty),你可以创建变换矩阵M,如下所示:
M = [ 1 0 t x 0 1 t y ] M= \begin{bmatrix} 1&0&t_x\\ 0&1&t_y \end{bmatrix} M=[1001txty]
可以将其设置为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()
注意:cv.warpAffine()函数的第三个参数是输出图像的大小,它应该是(宽,高)的形式, width=列数,height=行数。
通过改变图像矩阵实现图像旋转角度θ
M = [ c o s Θ − s i n Θ s i n Θ c o s Θ ] M=\begin{bmatrix} cos\Theta &-sin\Theta\\ sin\Theta & cos\Theta \end{bmatrix} M=[cosΘsinΘ−sinΘcosΘ]
OpenCV提供了可调旋转中心的缩放旋转,这样你可以在你喜欢的任何位置进行旋转。修正的变换矩阵由下式给出:
[ α β ( 1 − α ) ⋅ c e n t e r . x − β ⋅ c e n t e r . y − β α β ⋅ c e n t e r . x ( 1 − α ) ⋅ c e n t e r . y ] \begin{bmatrix} \alpha & \beta & \left ( 1-\alpha \right )\cdot center.x-\beta \cdot center.y \\ -\beta & \alpha & \beta \cdot center.x\left ( 1-\alpha \right )\cdot center.y \end{bmatrix} [α−ββα(1−α)⋅center.x−β⋅center.yβ⋅center.x(1−α)⋅center.y]
其中:
α = s c a l e ⋅ c o s Θ \alpha = scale\cdot cos\Theta α=scale⋅cosΘ
β = s c a l e ⋅ s i n Θ \beta = scale\cdot sin\Theta β=scale⋅sinΘ
为了找到这个转换矩阵,OpenCV提供了一个函数cv.getRotationMatrix2D
。以下示例将图像相对于中心旋转90度而不进行任何缩放。
img = cv.imread('messi5.jpg',0)
rows,cols = img.shape
M = cv.getRotationMatrix2D((cols/2,rows/2),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]])
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变换矩阵。
代码:
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)
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')
窗口显示: