目录
1 扩展缩放 2 平移 3 旋转 4 仿射变换 5 透视变换
cv2.resize(src, dsize, dst, fx, fy, interpolation)
INTER_NEAREST | 最近邻插值法 |
INTER_LINEAR | 双线性插值法(默认) |
INTER_AREA | 基于局部像素的重采样 |
INTER_CUBIC | 基于4x4像素邻域的3次插值法 |
INTER_LANCZOS4 | 基于8x8像素邻域的Lanczos插值 |
例如:
import cv2
import numpy as np
img = cv2.imread('test.jpg')
# 方法一 设置缩放比例
dst1 = cv2.resize(img, None, fx=0.8, fy=0.8, interpolation=cv2.INTER_CUBIC)
# 方法二 直接设置输出尺寸,注意输出尺寸必须为整型
height, width = img.shape[:2] # 获得原尺寸
dst2 = cv2.resize(img, (int(0.5*width), int(0.5*height)), interpolation=cv2.INTER_CUBIC)
while(1):
cv2.imshow('dst1', dst1)
cv2.imshow('dst2', dst2)
cv2.imshow('img', img)
if cv2.waitKey(1) & 0xFF == 27:
break
cv2.destroyAllWindows()
结果如下:
平移和旋转都是仿射变换的特例,所用函数都是cv2.warpAffine,只是转换矩阵M有所不同。
cv2.warpAffine(src, M, dsize, dst, flags, borderMode, borderValue)
–cv2.BORDER_CONSTANT 添加有颜色的常数值边界,还需要下一个参数(value)。
– cv2.BORDER_REFLECT边界元素的镜像。比如: fedcba|abcdefgh|hgfedcb
– cv2.BORDER_REFLECT_101 or cv2.BORDER_DEFAULT 跟上面一样,但稍作改动。例如: gfedcb|abcdefgh|gfedcba
– cv2.BORDER_REPLICATE重复最后一个元素。例如: aaaaaa| abcdefgh|hhhhhhh
– cv2.BORDER_WRAP 不知道怎么说了, 就像这样: cdefgh| abcdefgh|abcdefg
效果可在这篇文章中看到:https://blog.csdn.net/yukinoai/article/details/86423937
对于平移,变换矩阵M如下所示:
由于比较简单,直接使用 Numpy 数组构建这个矩阵(数据类型是 np.float32)即可,然后把它传给函数 cv2.warpAffine()。
例如:
import cv2
import numpy as np
img = cv2.imread('test.jpg', 0) # 以单通道灰度图像读入
rows, cols = img.shape
# 平移矩阵M:[[1,0,x],[0,1,y]]
M = np.float32([[1, 0, 200], [0, 1, 100]])
dst = cv2.warpAffine(img, M, (cols, rows))
while(1):
cv2.imshow('dst', dst)
cv2.imshow('img', img)
if cv2.waitKey(1) & 0xFF == 27:
break
cv2.destroyAllWindows()
结果如下:
平移和旋转都是仿射变换的特例,所用函数都是cv2.warpAffine,只是转换矩阵M有所不同。对于旋转,变换矩阵M可通过cv2.getRotationMatrix2D函数获得。
cv2.getRotationMatrix2D(center, angle, scale)
输出矩阵如下所示
其中α = scale · cosθ,β = scale· sinθ, 表示绕 center.x,center.y 旋转 θ
例如:
import cv2
import numpy as np
img = cv2.imread('test.jpg', 0) # 以单通道灰度图像读入
rows, cols = img.shape
# 这里的第一个参数为旋转中心,第二个为旋转角度,第三个为旋转后的缩放因子
# 可以通过设置旋转中心,缩放因子,以及窗口大小来防止旋转后超出边界的问题
M = cv2.getRotationMatrix2D((cols/2, rows/2), 45, 0.6)
# 第三个参数是输出图像的尺寸中心
dst = cv2.warpAffine(img, M, (cols, rows))
while(1):
cv2.imshow('src', img)
cv2.imshow('dst', dst)
if cv2.waitKey(1) & 0xFF == 27:
break
cv2.destroyAllWindows()
结果如下:
一般的仿射变换的转换矩阵M也可以通过 cv2.getAffineTransform获得,这个方法更加简便直观。
cv2.getAffineTransform(src,dst)
变换过程如下图所示,3个点一 一对应映射
例如:
import cv2
import numpy as np
from matplotlib import pyplot as plt
img = cv2.imread('test8.jpg')
rows, cols, ch = img.shape
img1 = cv2.imread('test.jpg')
rows1, cols1, ch1 = img1.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))
dst1 = cv2.warpAffine(img1, M, (cols, rows))
plt.subplot(221), plt.imshow(img), plt.title('Input')
plt.subplot(222), plt.imshow(dst), plt.title('Output')
plt.subplot(223), plt.imshow(img1), plt.title('Input')
plt.subplot(224), plt.imshow(dst1), plt.title('Output')
plt.show()
结果如下:
cv2.warpPerspective(src, M, dsize, dst, flags, borderMode, borderValue)
–cv2.BORDER_CONSTANT 添加有颜色的常数值边界,还需要下一个参数(value)。
– cv2.BORDER_REFLECT边界元素的镜像。比如: fedcba|abcdefgh|hgfedcb
– cv2.BORDER_REFLECT_101 or cv2.BORDER_DEFAULT 跟上面一样,但稍作改动。例如: gfedcb|abcdefgh|gfedcba
– cv2.BORDER_REPLICATE重复最后一个元素。例如: aaaaaa| abcdefgh|hhhhhhh
– cv2.BORDER_WRAP 不知道怎么说了, 就像这样: cdefgh| abcdefgh|abcdefg
效果可在这篇文章中看到:https://blog.csdn.net/yukinoai/article/details/86423937
转换矩阵M可通过以下函数获得:
cv2.getPerspectiveTransform(src, dst)
例如:
import cv2
import numpy as np
import matplotlib.pylab as plt
img = cv2.imread('test10.jpg')
rows, cols, ch = img.shape
# 设置标记点和目标点
markpoint = [[93, 651], [20, 197], [788, 540], [665, 20]]
dstpoint = [[0, 0], [352, 0], [0, 500], [352, 500]]
# 强调标记点
for i in markpoint:
cv2.circle(img, tuple(i), 10, (0, 255, 0), -1)
# 转换点的格式
pts1 = np.float32(markpoint)
pts2 = np.float32(dstpoint)
# 生成透视矩阵
M = cv2.getPerspectiveTransform(pts1, pts2)
# 转换
dst = cv2.warpPerspective(img, M, (352, 500))
plt.subplot(121), plt.imshow(img), plt.title('Input')
plt.subplot(122), plt.imshow(dst), plt.title('Output')
plt.show()
结果如下: