(Python)从零开始,简单快速学机器仿人视觉Opencv—第十节:五种常见的几何变换

165
0
2020年12月24日 09时12分

涉及函数:

cv2.getPerspectiveTransform()
cv2.warpAffine()
cv2.warpPersperctive()

 

名称讲解:

 

通道数:指的是一个像素点由几个元素产生,有几个元素就有几条通道。如:一张RGB的图片,他上面的一个像素点就有三个元素组成(三通道),分别是B(Blue),G(Green),R(Red),所以这张图片就是三通道的;而一张灰度图,上面的每一个像素点都只由灰度值[0-255]来决定,所以他就是单通道的,通道数为1.

 

任务1:扩展缩放

 

如果只是改变图像的尺寸大小,cv2.resize()可以实现这个功能。在缩放时推荐cv2.INTER_AREA,在拓展时推荐cv2.INTER_CUBIC(慢)和cv2.INTER_LINEAR。默认情况下所有改变图像尺寸大小的操作使用的是插值法都是cv2.INTER_LINEAR。

 

import cv2

img = cv2.imread('45.jpg')
#下面的None本应该是输出图像的尺寸,但是因为后面我们设置了缩放因子,所以,这里为None
res = cv2.resize(img,None,fx=2,fy=2,interpolation=cv2.INTER_CUBIC)
#or
#这里直接设置输出图像的尺寸,所以不用设置缩放因子
height , width =img.shape[:2]
res = cv2.resize(img,(2*width,2*height),interpolation=cv2.INTER_CUBIC)

cv2.imshow('res',res)
cv2.imshow('img',img)
cv2.waitKey(0)&0xFF #或者cv2.waitKey(0)      
cv2.destroyAllWindows()

 

任务2:平移

 

如果想要沿(x,y)方向移动,移动的距离为(tx,ty)可以以下面方式构建移动矩阵。

 

1

 

可以使用Numpy数组构建矩阵,数据类型是np.float32,然后传给函数cv2.warpAffine()
函数cv2.warpAffine() 的第三个参数的是输出图像的大小,它的格式应该是图像的(宽,高)。应该记住的是图像的宽对应的是列数,高对应的是行数。

 

任务3:旋转

 

对一个图像旋转角度θ,需要使用下面的旋转矩阵。

 

2

 

但OpenCVC允许在任意地方进行旋转,所以矩阵应该为

 

3

 

其中α = scale · cos θ
为构建旋转矩阵,OpenCV提供了一个函数cv2.getRotationMatrix2D。

 

import cv2

img = cv2.imread('45.jpg',0)

#对象为灰度图时的shape不会返回通道数
rows,cols=img.shape

#这里的第一个参数为旋转中心,第二个为旋转角度,第三个为旋转后的缩放因子
#可以通过设置旋转中心,缩放因子以及窗口大小来防止旋转后超出边界的问题。
M=cv2.getRotationMatrix2D((cols/2,rows/2),45,0.6)

#第三个参数是输出图像的尺寸中心
dst=cv2.warpAffine(img,M,(2*cols,2*rows))
cv2.imshow('img',dst)
cv2.waitKey(0)&0xFF #或者cv2.waitKey(0)
cv2.destroyAllWindows()

 

任务4:仿射变换

 

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

 

import cv2
import numpy as np

img=cv2.imread('draw.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 = cv2.getAffineTransform(pts1,pts2)

dst = cv2.warpAffine(img,M,(cols,rows))

cv2.imshow('input',img)
cv2.imshow('output',dst)
cv2.waitKey(0)&0xff #或者cv2.waitKey(0)
cv2.destroyAllWindows()

 

任务5:透视变换

 

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

 

import cv2
import numpy as np

img=cv2.imread('sudokusmall.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=cv2.getPerspectiveTransform(pts1,pts2)

dst=cv2.warpPerspective(img,M,(300,300))

cv2.imshow('input',img)
cv2.imshow('output',dst)
cv2.waitKey(0)&0xff #或者cv2.waitKey(0)
cv2.destroyAllWindows()

 

总结

(本系列每周不定期更新,谢谢大家支持!)

 

发表评论

后才能评论