五、图像的变换
1、图像的基本变换
1.1 图像的缩放
resize
用法:
cv2.resize(src, dsize, dst, fx, fy, interpolation)
参数说明:
- src:进行缩放的图像
- dsize:缩放之后图像的大小(元组或列表表示即可)
- dst:可选参数,缩放之后的输出图像
- fx, fy:x轴和y轴的缩放比,即宽度和高度的缩放比
- interpolation:插值算法,主要有以下几种:
算法 | 描述 |
INTER_NEAREST | 邻近插值,速度快,效果差 |
INTER_LINEAR | 双线性插值,使用原图中的4个点进行插值(默认) |
INTER_CUBIC | 三次插值,原图中的16个点 |
INTER_AREA | 区域插值,效果最好,计算时间最长 |
1、原图像:480 * 640
2、dsize = (320, 240) 缩放之后的图像:
new_dog = cv2.resize(dog, (320, 240))
3、fx=0.7, fy=0.7 缩放之后的图像:
new_dog = cv2.resize(dog, None, fx=0.7, fy=0.7)
4、INTER_NEAREST(左)、INTER_LINEAR(右)
5、INTER_CUBIC(左)、INTER_AREA(右)
代码实现:
import cv2 dog = cv2.imread('../resource/r_dog.jpg') # new_dog = cv2.resize(dog, (320, 240)) # new_dog = cv2.resize(dog, None, fx=0.7, fy=0.7) new_dog = cv2.resize(dog, None, fx=0.7, fy=0.7, interpolation=cv2.INTER_CUBIC) cv2.imshow('dog', dog) cv2.imshow('new_dog', new_dog) cv2.waitKey(0) cv2.destroyAllWindows()
1.2 图像的翻转
flip()
用法:
cv2.flip(src, flipCode)
参数说明:
- src:进行翻转的图像
- flipCode
- flipCode = 0:表示上下翻转
- flipCode > 0:表示左右翻转
- flipCode < 0:上下 + 左右
1、flipCode = 0:表示上下翻转
up_down = cv2.flip(cat, flipCode=0)
2、flipCode > 0:表示左右翻转
left_right = cv2.flip(cat, flipCode=1)
3、flipCode < 0:上下 + 左右
up_down_left_right = cv2.flip(cat, flipCode=-1)
代码实现:
import cv2 import numpy as np cat = cv2.imread('../resource/r_cat.jpg') up_down = cv2.flip(cat, flipCode=0) cv2.imshow('up_down', np.hstack((cat, up_down))) cv2.waitKey(0) cv2.destroyAllWindows()
1.3 图像的旋转
rotate()
用法:
rotate(src, rotateCode)
参数说明:
- src:进行旋转的图像
- rotateCode
rotateCode | 描述 |
ROTATE_90_CLOCKWISE | 顺时针 90° |
ROTATE_180 | 180° |
ROTATE_90_COUNTERCLOCKWISE | 逆时针 90° |
原图像 VS 旋转180°
代码实现:
import cv2 import numpy as np dog = cv2.imread('../resource/r_dog.jpg') new = cv2.rotate(dog, cv2.ROTATE_180) cv2.imshow('dog', np.hstack((dog, new))) cv2.waitKey(0) cv2.destroyAllWindows()
2、图像的仿射变换
仿射变换是图像旋转、缩放、平移的总称。
具体的做法是通过一个矩阵和原图像坐标进行计算,得到新的坐标,完成变换,所以关键就是这个变换矩阵。
warpAffine
用法:
cv2.warpAffine(src, M, dsize, dst, flags, borderMode, borderValue)
参数说明:
- src:进行变换的图像
- M:变换矩阵
- dsize:输出图像大小
- dst:可选参数,缩放之后的输出图像
- flags:与resize中的插值算法一致
- borderMode:边界外推法标志
- borderValue:填充边界的值
2.1 图像平移
矩阵中的每个像素由(x, y)组成,因此,其变换矩阵是2 * 2的矩阵。
平移向量为2 * 1的向量,所在平移矩阵为2 * 3矩阵
代码实现: x, y 均平移100
import cv2 import numpy as np # 导入图像 dog = cv2.imread('../resource/r_dog.jpg') h, w, ch = dog.shape M = np.float32([[1, 0, 100], [0, 1, 100]]) # 注意:先宽度、再高度 new = cv2.warpAffine(dog, M, (w, h)) cv2.imshow('dog', np.hstack((dog, new))) cv2.waitKey(0) cv2.destroyAllWindows()
2.2 获取变换矩阵
仿射变换的难点就是计算变换矩阵,OpenCV提供了计算变换矩阵的API:
getRotationMatrix2D()
用法:
cv2.getRotationMatrix2D(center, angle, scale)
参数说明:
- center:中心点,以图像的哪个点作为旋转的中心点
- angle:角度,旋转的角度,按照逆时针旋转
- scale:缩放比例,想把图像进行什么样的缩放
代码实现: 以原图像中心点逆时针旋转45°
import cv2 import numpy as np # 导入图像 dog = cv2.imread('../resource/r_dog.jpg') h, w, ch = dog.shape # 获取变换矩阵 M = cv2.getRotationMatrix2D((w / 2, h / 2), 45, 1.0) new = cv2.warpAffine(dog, M, (w, h)) cv2.imshow('dog', np.hstack((dog, new))) cv2.waitKey(0) cv2.destroyAllWindows()
getAffineTransform()
用法:
cv2.getAffineTransform(src, dst)
参数说明:
- src:原目标的3个点
- dst:对应变换后的3个点
通过三个点可以确定变换后的位置,相当于解方程,三个点对应三个方程,能解出偏移的参数和旋转的角度。
代码实现:
import cv2 import numpy as np # 导入图像 dog = cv2.imread('../resource/r_dog.jpg') h, w, ch = dog.shape src = np.float32([[100, 200], [200, 100], [200, 300]]) dst = np.float32([[100, 150], [360, 200], [280, 120]]) M = cv2.getAffineTransform(src, dst) new = cv2.warpAffine(dog, M, (w, h)) cv2.imshow('dog', np.hstack((dog, new))) cv2.waitKey(0) cv2.destroyAllWindows()
3、图像的透视变换
透视变换就是将一种坐标系变成另一种坐标系。简单的来说,可以把一张“斜”的图像变“正”。
warpPerspective()
用法:
cv2.warpPerspective(src, M, dsize, dst, flags, borderMode,borderValue)
对于透视变换来说,M是一个3 * 3的矩阵。
getPerspectiveTransform()
用法:
cv2.getPerspectiveTransform(src, dst, solveMethod)
获取透视变换的变换矩阵,需要4个点,即图像的4个角。
代码实现:
import cv2 import numpy as np # 导入图像 six = cv2.imread('../resource/six.jpg') print(six.shape) src = np.float32([[100, 100], [670, 100], [100, 960], [670, 960]]) dst = np.float32([[0, 0], [620, 0], [0, 860], [570, 860]]) M = cv2.getPerspectiveTransform(src, dst) new = cv2.warpPerspective(six, M, (570, 860)) cv2.imshow('six', six) cv2.imshow('new', new) cv2.waitKey(0) cv2.destroyAllWindows()