几何变换
目标: 了解图片的几何转换,eg:平移,旋转,仿射变换 etc
转换
opencv 提供了2种转换函数 cv.warpAffine
和 cv.warpPerspective
cv.warpAffine 需要 2x3 转换矩阵,而 cv.warpPerspective 需要 3x3 转换矩阵作为输入.
扩展
Scaling 是用来重新定义图片尺寸. OpenCV 提供 cv.resize()
方法来改变图片尺寸.
使用了不同的插值方法,较好的插值方法是cv.INTER_AREA用于收缩, cv.INTER_CUBIC (slow) & 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,如下所示:
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()
旋转
通过变换矩阵将图片进行旋转:
旋转矩阵如下,center 为旋转中心:
获取旋转矩阵的方法:
import numpy as np
import cv2 as cv
from matplotlib import pyplot as plt
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。
import numpy as np
import cv2 as cv
from matplotlib import pyplot as plt
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变换矩阵。
import numpy as np
import cv2 as cv
from matplotlib import pyplot as plt
img = cv.imread('sudoku.png')
rows,cols,ch = img.shape
# 选择图像上的四个点,
pts1 = np.float32([[0,0],[cols,0],[0,rows],[cols,rows]])
# 变换后对应的点的坐标
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()