当前位置: 代码迷 >> 综合 >> 7. 图像的几何变换-cv2.resize()、cv2.warpAffine()、cv2.getRotationMatrix2D()、cv2.getAffineTransform()、透视变换
  详细解决方案

7. 图像的几何变换-cv2.resize()、cv2.warpAffine()、cv2.getRotationMatrix2D()、cv2.getAffineTransform()、透视变换

热度:71   发布时间:2023-12-15 12:47:10.0

1. 改变图像的大小-cv2.resize()

函数原型:cv2.resize(src,  dst, Size, fx, fy, interpolation)

参数说明:1. src 输入图片 2. dst 输出图片 3.size 输出图片的大小 4. fx、fy:沿水平轴、垂直轴的缩放因子(宽度、高度) 5.插入方式,默认为INTER_LINEAR.

插入方式interpolation有以下几种:

INTER_NEAREST

最近邻插值

INTER_LINEAR

双线性插值(默认设置)

INTER_AREA

使用像素区域关系进行重采样。

INTER_CUBIC

4x4像素邻域的双三次插值

INTER_LANCZOS4

8x8像素邻域的Lanczos插值

代码如下:

def resize_demo(image):print("Origin size:", image.shape)# 第一种方法:通过fx,fy缩放因子res = cv.resize(image, None, fx=1, fy=3, interpolation=cv.INTER_CUBIC)  # fx宽 fy高print("After resize 1 size:", res.shape)# 第二种方法:直接设置输出图像的尺寸,所以不用设置缩放因子height,width = image.shape[:2]res=cv.resize(image,(2*width,2*height),interpolation=cv.INTER_CUBIC)print("After resize 2 size:", res.shape)while(1):cv.imshow('res',res)cv.imshow('img',image)if cv.waitKey(1) & 0xFF == 27:break

注:cv2.resize():要缩小图像,一般推荐使用CV_INETR_AREA(区域插值)来插值;若要放大图像,推荐使用CV_INTER_LINEAR(线性插值).

2. 图像的偏移- cv2.warpAffine()

图像的平移也分为两步:首先定义好图像的平移矩阵,分别指定x方向(宽)和y方向上(高)的平移量tx和ty,平移矩阵(2 X 3)的形式如下:

代码如下:

def move_demo(image):rows, cols = image.shape[:2]M = np.float32([[1, 0, 100], [0, 1, 50]])    # M为平移矩阵,100为宽移动的距离,50为高dst = cv.warpAffine(image, M, (cols, rows))  # 仿射变换函数   (cols, rows):平移后图像的大小cv.imshow('image', dst)

 3. 图像的旋转- cv2.getRotationMatrix2D()

这个函数可以在任何位置进行旋转变换,它的旋转矩阵为:

这个函数有三个参数:旋转中心,旋转角度,旋转后图像的缩放比例。

然后再使用函数cv2.warpAffine()利用得到的M对原始图像进行变换即可。

代码如下:

def rotation_demo(img):rows, cols = img.shape[:2]# 将图像相对于中心旋转90度,而不进行任何缩放。旋转中心,角度,缩放比率M = cv.getRotationMatrix2D((cols / 2, rows / 2), 90, 1)dst = cv.warpAffine(img, M, (cols, rows))cv.imshow('original', img)cv.imshow('result', dst)cv.waitKey(0)cv.destroyAllWindows()

4. 图像的仿射变换-cv2.getAffineTransform()

仿射变换,又称仿射映射,是指在几何中,一个向量空间进行一次线性变换并接上一个平移,变换为另一个向量空间。仿射变换需要一个M矩阵,但是由于仿射变换比较复杂,一般直接找很难找到这个矩阵,opencv提供了根据变换前后三个点的对应关系来自动求解M的函数,这个函数就是cv2.getAffineTransform(),参数如下:

  1. src:原始图像中的三个点的坐标
  2. dst:变换后的这三个点对应的坐标
  3. M:根据三个对应点求出的仿射变换矩阵

然后再使用函数cv2.warpAffine()利用得到的M对原始图像进行变换即可。

代码如下:

def affine_demo(img):rows, cols, ch = img.shapepts1 = 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()

5. 透视变换-cv2.getPerspectiveTransform()、cv2.warpPerspective()

透视变换(Perspective Transformation)是将成像投影到一个新的视平面(Viewing Plane),也称作投影映射(Projective Mapping)。

5.1 cv2.getPerspectiveTransform(src, dst)

参数说明:

  • src:源图像中待测矩形的四点坐标

  • sdt:目标图像中矩形的四点坐标

  • 返回值:由源图像中矩形到目标图像矩形变换的矩阵 ,得到变换矩阵。

5.2 cv2.warpPerspective(src, M, dsize, dst=None, flags=None, borderMode=None, borderValue=None)

参数说明:

  • src:输入图像

  • M:变换矩阵

  • dsize:目标图像shape

  • flags:插值方式,interpolation方法INTER_LINEAR或INTER_NEAREST

  • borderMode:边界补偿方式,BORDER_CONSTANT or BORDER_REPLICATE

  • borderValue:边界补偿大小,常值,默认为0

  • 作用:进行透视变换。

代码如下:

def perspective_demo(img):rows, cols, ch = img.shapepts1 = np.float32([[56, 65], [368, 52], [28, 387], [389, 390]])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()

 

  相关解决方案