基于Python的OpenCV基础入门——图像的几何变换(2)
- 仿射变换
- 透视变换
- 仿射变化和透视变换的代码实现:
仿射变换
仿射变换是一种仅在二维平面中发生的几何变形,通俗的理解原来的直线变换之后还是直线,平行线变换之后还是平行线。OpenCV关于仿射变换提供了warpAffine方法,可以实现图像的平移、旋转、倾斜等。
image = cv2.warpAffine(src, M, dsize, flags,borderMode, borderValue)
参数:
src:原始图像。
M:一个2行3列的矩阵,根据此矩阵的值变换原图中的像素位置,决定做哪种变换。
dsize:输出图像的尺寸大小。
flags:可选参数,插值方式,建议使用默认值。
borderMode:可选参数,边界类型,建议使用默认值。
borderValue:可选参数,边界值,默认为0,建议使用默认值。
在实际的应用中最常使用的是图像的旋转,OpenCV提供了getRotationMatrix2D方法自动计算旋转图像的M矩阵。
M = cv2.getRotationMatrix2D(center, angle,scale)
参数:
center:旋转的中心点坐标 (x, y)。
angle:旋转的角度(不是弧度)。正数表示逆时针旋转,负数表示顺时针旋转。
scale:缩放比例,浮点类型。如果取值1,表示图像保持原来的比例。
透视变换
图像透视变换的本质是将图像投影到一个新的视平面,从不同的角度观察物体,会看到不同的变形画面。
dst = cv2.warpPerspective(src, M, dsize, flags,borderMode, borderValue)
参数:
src:原始图像。
M:一个3行3列的矩阵,根据此矩阵的值变换原图中的像素位置。
dsize:输出图像的尺寸大小 (rows,cols)。
flags:可选参数,插值方式,建议使用默认值。
borderMode:可选参数,边界类型,建议使用默认值。
borderValue:可选参数,边界值,默认为0,建议使用默认值。
在warpPerspective方法中的参数也有一个M矩阵,这个矩阵通过getPerspectiveTransform方法计算得到。
M = cv2.getPerspectiveTransform(pos1, pos2)
参数:
Pos1和pos2:原图4个点坐标和透视后的四个点的坐标,例如:[[0, 0], [1, 0], [0, 1],[1, 1]]。
仿射变化和透视变换的代码实现:
import cv2
import matplotlib.pyplot as plt
image = cv2.imread("img/cat.jpg")
image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
image_shape = image.shape # 获取图像的垂直尺寸、水平尺寸、通道数(image.shape[0],image.shape[1],image.shape[2])
M1 = cv2.getRotationMatrix2D((image_shape[0] / 2, image_shape[1] / 2), 45, 1) # 求出绕图像中心逆时针旋转45度的旋转矩阵
image_clockwise = cv2.warpAffine(image, M1, (image_shape[0], image_shape[1])) # 图像旋转
M2 = cv2.getRotationMatrix2D((image_shape[0] / 2, image_shape[1] / 2), -45, 1) # 求出绕图像中心顺时针旋转45度的旋转矩阵
image_anticlockwise = cv2.warpAffine(image, M2, (image_shape[0], image_shape[1])) # 图像旋转
image_list = [image, image_clockwise, image_anticlockwise]
titles = ["Original", "anticlockwise", "clockwise"]
for i in range(3):
plt.subplot(1, 3, i + 1), plt.imshow(image_list[i], 'gray')
plt.xticks([]), plt.yticks([])
plt.show()
代码实现效果图:
import cv2
import matplotlib.pyplot as plt
import numpy as np
image = cv2.imread("img/cat.jpg")
image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
image_shape = image.shape # 获取图像的垂直尺寸、水平尺寸、通道数(image.shape[0],image.shape[1],image.shape[2])
h, w = image_shape[:2] # 获取高和宽
pts1 = np.float32([[0, 0], [0, h - 1], [w - 1, h - 1], [w - 1, 0]]) # 获取原图的四个角点
pts2 = np.float32([[0, 0], [200, h - 36], [w - 36, h - 36], [w - 1, 0]]) # 变换后的四个顶点坐标
M = cv2.getPerspectiveTransform(pts1, pts2) # 先得确定透视变换的系数
dst = cv2.warpPerspective(image, M, (500, 526)) # 对原图进行仿射变换
image_list = [image, dst]
titles = ["Original", " perspective"]
for i in range(2):
plt.subplot(1, 2, i + 1), plt.imshow(image_list[i], 'gray')
plt.title(titles[i])
plt.xticks([]), plt.yticks([])
plt.show()
代码实现效果图: