变换
opencv提供了两个转换函数cv.warpAffine和cv.warpPersective,可以使用它们进行各种转换。cv.warpAffine采用2x3转换矩阵,而cv.warpPerspective采用3x3转换矩阵作为输入。
缩放
缩放只是调整图像的大小。为此,opencv带有一个函数cv.resize()。图像的大小可以手动指定,也可以指定缩放比例。也可使用不同的插值会方法。首选的插值方法是cv.INTER_AREA用于缩小,cv.INTER_CUBIC(慢)和cv.INTER_LINEAR用于缩放。默认情况下,出于所有调整大小的目的,使用插值方法为cv.INTER_LINEAR。
import cv2 as cv img=cv.imread('./images/lena.jpeg') # 缩小 img_small1=cv.resize(img,None,fx=0.5,fy=0.5,interpolation=cv.INTER_AREA) height,width=img.shape[:2] img_small2=cv.resize(img,(int(0.5*width),int(0.5*height)),interpolation=cv.INTER_AREA) # 放大 img_big1=cv.resize(img,None,fx=2,fy=2,interpolation=cv.INTER_CUBIC) img_big2=cv.resize(img,(2*width,2*height),interpolation=cv.INTER_CUBIC) print(img.shape) # (256, 256, 3) print(img_small1.shape) # (128, 128, 3) print(img_small2.shape) # (128, 128, 3) print(img_big1.shape) # (512, 512, 3) print(img_big2.shape) # (512, 512, 3) cv.imshow('img',img) cv.imshow('img_small1',img_small1) cv.imshow('img_small2',img_small2) cv.imshow('img_big1',img_big1) cv.imshow('img_big2',img_big2) cv.waitKey(0) cv.destroyAllWindows()
平移
如果想要沿(x,y)方向移动,移动的距离为(tx,ty),可以以下面方式构建移动矩阵。

可以使用Numpy数组构建矩阵,数据类型为np.float32,然后传给函数cv.warpAffine(),函数的第三个参数是输出图像的大小,它的格式应该是图像的(宽,高)。应该记住的是图像的宽对应的是列数,高对应的是行数。
import numpy as np import cv2 as cv img=cv.imread('./images/lena.jpeg') rows,cols=img.shape[:2] # 设置移动矩阵 M=np.array([[1,0,100],[0,1,50]],dtype=np.float32) dst=cv.warpAffine(img,M,(cols,rows)) cv.imshow('dst',dst) cv.waitKey(0) cv.destroyAllWindows()
旋转
图像旋转角度为θ是通过以下的变换矩阵实现的:

但opencv允许在任意地方进行旋转,所以矩阵为:

其中α = scale · cos θ,β=scale·sin θ
为了找到此转换矩阵,opencv提供了一个函数cv.getRotationMatrix2D。
import cv2 as cv img=cv.imread('./images/lena.jpeg') rows,cols=img.shape[:2] # 第一个参数为旋转中心,第二个参数为旋转角度,第三个为旋转后的缩放因子 # 可以通过设置旋转中心,缩放因子以及窗口大小来防止旋转后超出边界的问题 M=cv.getRotationMatrix2D((cols/2,rows/2),45,0.6) dst=cv.warpAffine(img,M,(cols,rows)) while(1): cv.imshow('img',dst) if cv.waitKey(1)&0XFF==27: break cv.destroyAllWindows()
仿射变换
在仿射变换中,原始图像中的所有平行线在输出图像中仍将平行。为了找到变换矩阵,需要输入图像中的三个点及其在输出图像中的对应位置。然后cv.getAffineTransform将创建一个2x3矩阵,该矩阵将传递给cv.warpAffine。
import cv2 as cv import numpy as np from matplotlib import pyplot as plt img=cv.imread('./images/lena.jpeg') img=img[:,:,[2,1,0]] 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个点,在输出图像上需要相应的点。在这四个点中,其中三个不应共线。然后可以通过函数cv.getPerspectiveTransform找到变换矩阵。然后将cv.warpPerspective应用于3x3转换矩阵。
import cv2 as cv import numpy as np from matplotlib import pyplot as plt img=cv.imread('./images/lena.jpeg') print(img.shape) img=img[:,:,[2,1,0]] rows,cols,ch=img.shape pts1=np.float32([[56,65],[26,52],[28,86],[239,130]]) pts2=np.float32([[0,0],[200,0],[0,230],[230,780]]) M=cv.getPerspectiveTransform(pts1,pts2) dst=cv.warpPerspective(img,M,(cols,rows)) plt.subplot(121) plt.imshow(img) plt.title('input') plt.subplot(122) plt.imshow(dst) plt.title('output') plt.show()
posted on
浙公网安备 33010602011771号