Opencv3学习笔记(C++&Python双语)---几何变换

图像的几何变换有两种,仿射变换与透视变换。两者的区别参照教程《学习Opencv3》第11章常见的图像变换。

此外推荐一篇文章 https://www.cnblogs.com/shine-lee/p/10950963.html   仿射变换及其变换矩阵的理解  ,下面的图片

均转载于此博客。

仿射变换使用2*3矩阵,透视变换采用3*3矩阵。仿射变换:平移、旋转、放缩、剪切、反射,仿射变换的特点是变换前的两条平行线变换后仍然平行。透视变换用于计算一个特定观察者感觉三维平面的方法,简单讲就是同一个物体,观察者在不同的位置看到的几何图形是不一样的(达芬奇画鸡蛋的故事),可以看看绘画中的透视,小时候很好奇在一张纸上可以画出三维效果,仔细观察就发现两条平行直线在透视图中是不平行的,因为视觉错觉就会产生三维效果,既透视效果,喜欢画画的同学应该很好理解透视。这也就是为什么仿射变换只需要3个点而透视变换需要4个点。距离观察视点越远的地方,两条直线越趋于相交。仿射变换是透视变换的一个子集。

 

Basic set of 2D planar transformations

 affine transformations

 

 

Opencv中关于几何变换的函数:

1.cv.resize()   均匀调整图像

2.密集仿射变换函数cv.warpAffine() ,计算映射矩阵的函数cv.getAffineTransform() ,计算旋转映射矩阵的函数cv.getRotationMatrix2D()

3.密集透视变换函数cv.warpPerspective() 以及相对应的计算透视映射矩阵的函数cv.getPerspectiveTransform() 

python代码(C++代码较复杂,后面抽空补上)

均匀缩放

img = cv.imread("F:\\L-opencv3\\picture\\lena.jpg")
#下面的None本应该是输出图像的尺寸,但是因为后面我们设置了缩放因子,所以,这里为None
res = cv.resize(img,None,fx=2,fy=2,interpolation=cv.INTER_CUBIC)
#或者
#这里直接设置输出图像的尺寸,所以不用设置缩放因子
height,width = img.shape[:2]
res = cv.resize(img,(2*width,2*height),interpolation=cv.INTER_CUBIC)
cv.imshow("Input",img)
cv.imshow("Output",res)
cv.waitKey(0)
cv.destroyAllWindows()

输出图像:

旋转

为了方便matplotlib显示图像,把原图像转为灰度图,因为matplotlib显示Opencv读取的彩色图像会出问题前者RGB,后者BRG,可以用split分离再用merge重新组合通道可正确显示,这里演示仿射变换,用灰度图就够了。
 

img = cv.cvtColor((cv.imread("F:\\L-opencv3\\picture\\lena.jpg")),cv.COLOR_BGR2GRAY)
rows,cols = img.shape
M = cv.getRotationMatrix2D((cols/2,rows/2),45,0.6)
dst = cv.warpAffine(img,M,(2*cols,2*rows))
plt.subplot(121),plt.imshow(img,'gray'),plt.title('Input')
plt.subplot(122),plt.imshow(dst,'gray'),plt.title("Output")
plt.show()

输出图像效果:

仿射变换

在仿射变换中,原图中所有平行线在结果图像中同样平行。为创建这个矩阵,需要从原图像中找到三个点以及他们在输出图像中的位置,然后cv2.getAffineTransForm()会创建一个2X3的矩阵。最后这个矩阵会被传给函数cv2.warpAffine()

img = cv.cvtColor((cv.imread("F:\\L-opencv3\\picture\\lena.jpg")),cv.COLOR_BGR2GRAY)
rows,clos = img.shape

pst1 = np.float32([[50,50],[200,50],[50,200]])
pst2 = np.float32([[10,100],[200,50],[100,250]])

M = cv.getAffineTransform(pst1,pst2)
dst = cv.warpAffine(img,M,(cols,rows))

plt.subplot(121),plt.imshow(img,'gray'),plt.title('Input')
plt.subplot(122),plt.imshow(dst,'gray'),plt.title('Output')
plt.show()

 

 输出图像效果:

透视变换 

对于视角变换,我们需要一个3x3变换矩阵。在变换前后直线还是直线。需要在原图上找到4个点,以及他们在输出图上对应的位置,这四个点中任意三个都不能共线,可以有函数cv2.getPerspectiveTransform()构建,然后这个矩阵传给函cv2.warpPerspective()

img = cv.cvtColor((cv.imread("F:\\L-opencv3\\picture\\lena.jpg")),cv.COLOR_BGR2GRAY)
rows,clos = img.shape

pts1 = np.float32([[56,65],[152,52],[28,213],[232,235]])
pts2 = np.float32([[0,0],[252,0],[0,252],[252,252]])

M = cv.getPerspectiveTransform(pts1,pts2)

dst = cv.warpPerspective(img,M,(300,300))
plt.subplot(121),plt.imshow(img,'gray'),plt.title("Input")
plt.subplot(122),plt.imshow(dst,'gray'),plt.title("Output")
plt.show()

输出图像效果:

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值