什么是仿射变换?
![opencv实现仿射变换_第1张图片](http://img.e-com-net.com/image/info8/50dc041fdc3c4d559749aeba711b3e45.jpg)
![opencv实现仿射变换_第2张图片](http://img.e-com-net.com/image/info8/dfc3684e1bb641d4999fae11b6981219.jpg)
![opencv实现仿射变换_第3张图片](http://img.e-com-net.com/image/info8/c6dd1f70eaa54351b24e0a38a1d36b83.jpg)
代码实现
import numpy as np
import cv2 as cv
import matplotlib.pyplot as plt
from pylab import mpl
mpl.rcParams['font.sans-serif'] = ['SimHei']
img = cv.imread("lena.png")
rows , cols = img.shape[:2]
pts1 = np.float32([[50,50],[200,50],[50,200]])
pts2 = np.float32([[100,100],[200,50],[100,250]])
M = cv.getAffineTransform(pts1,pts2)
dst = cv.warpAffine(img,M,(cols,rows))
fig,axes = plt.subplots(nrows=1,ncols=2,figsize=(10,8),dpi=100)
axes[0].imshow(img[:,:,::-1])
axes[0].set_title("原图")
axes[1].imshow(dst[:,:,::-1])
axes[1].set_title("放射后结果")
plt.show()
代码讲解
首先,导入所需的库:
import numpy as np
import cv2 as cv
import matplotlib.pyplot as plt
然后,读取图像:
img = cv.imread("lena.png")
这里假设存在名为"lena.png"的图像文件,使用cv.imread()函数将其读取为一个NumPy数组对象,并赋值给变量img。
接下来,定义仿射变换所需的坐标点:
pts1 = np.float32([[50,50],[200,50],[50,200]])
pts2 = np.float32([[100,100],[200,50],[100,250]])
pts1是原图中的三个点的坐标,pts2是对应的目标仿射后的三个点的坐标。这里选择了两个三角形形状的区域作为示例。
然后,通过这些坐标点获取仿射变换的矩阵:
M = cv.getAffineTransform(pts1,pts2)
使用cv.getAffineTransform()函数根据这两组对应的点,计算得到仿射变换的矩阵,赋值给变量M。
接着,进行仿射变换操作:
dst = cv.warpAffine(img,M,(cols,rows))
使用cv.warpAffine()函数对图像进行仿射变换,将原图img和变换矩阵M作为参数传入,得到仿射后的结果赋值给变量dst。
最后,使用Matplotlib库显示原图和仿射后的结果:
fig,axes = plt.subplots(nrows=1,ncols=2,figsize=(10,8),dpi=100)
axes[0].imshow(img[:,:,::-1])
axes[0].set_title("原图")
axes[1].imshow(dst[:,:,::-1])
axes[1].set_title("仿射后结果")
plt.show()
通过创建一个包含2个子图的Figure对象,并调用imshow()函数分别在两个子图上显示原图和仿射后的结果。set_title()函数用于设置子图的标题。最后,使用plt.show()函数显示图像。
注意,代码中的cols和rows是通过img.shape[:2]获取的图像的行数和列数,用于指定仿射变换结果的大小。
效果展示
![opencv实现仿射变换_第4张图片](http://img.e-com-net.com/image/info8/ba7b00c1dd3a4ca482837a829d6839dd.jpg)