import cv2
import matplotlib.pyplot as plt
import numpy as np
img = cv2.imread('fig3.jpg')
图像变换
图像平移
- cv2.warpAffine(src, M, dsize, flags, borderMode, borderValue)
- src: 输入图像
- M:变换矩阵,为inputAdarray类型的2*3的变换矩阵。
- dsize:输出图像的大小
- flags:插值方法的组合(int类型),默认为cv2.INTER_LINEAR(线性插值)
此外还有:cv2.INTER_AREA(区域插值)
cv2.INTER_NEAREST(最近邻插值)
cv2.INTER_CUBIC(三次样条插值)
cv2.INTER_LANCZOS4(Lanczos插值) - borderMode:边界像素模式(int类型)
- borderValue:边界填充值;默认为0。
img_path = "fig3.jpg"
img = cv2.imread(img_path)
img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
M = np.float32([[1, 0, 50], [0, 1, 25]]) # x轴移动50, y轴移动100
h, w = img.shape[:2]
res = cv2.warpAffine(img, M, (2 * w, 2 * h))
print('w:', w, 'h:', h)
plt.subplot(1, 2, 1)
plt.imshow(img)
plt.subplot(1, 2, 2)
plt.imshow(res)
plt.show()
图像缩放
- cv2.resize(src, dsize=None, fx, fy, interpolation)
- src:原图
- dsize:输出图像尺寸,与比例因子二选一
- fx:沿水平轴的比例因子
- fy:沿垂直轴的比例因子
- interpolation:插值方法
- cv2.INTER_NEAREST(最近邻插值) 默认
- cv2.INTER_LINEAR(线性插值)
- cv2.INTER_CUBIC(三次样条插值)
- cv2.INTER_LANCZZOS4(Lanczos插值)
- cv2.INTER_AREA(区域插值)
img_resize = img.copy()
img_resize = cv2.cvtColor(img_resize, cv2.COLOR_BGR2RGB)
res = cv2.resize(img_resize, None, fx=0.5, fy=0.5, interpolation=cv2.INTER_AREA)
res2 = cv2.resize(img_resize, (400, 300), cv2.INTER_AREA)
plt.subplot(2, 1, 1)
plt.imshow(res)
plt.subplot(2, 1, 2)
plt.imshow(res2)
plt.show()
图像旋转
设点
P
0
(
x
0
,
y
0
)
P_0(x_0, y_0)
P0(x0,y0)逆时针旋转
θ
\theta
θ角后的对应点为
P
(
x
,
y
)
P(x, y)
P(x,y),那么,旋转后点
P
(
x
,
y
)
P(x, y)
P(x,y)的坐标是:
x
=
r
c
o
s
(
α
+
θ
)
=
r
c
o
s
α
c
o
s
θ
−
r
s
i
n
α
s
i
n
θ
=
x
0
c
o
s
θ
−
y
0
s
i
n
θ
x = rcos(\alpha+\theta)=rcos\alpha cos\theta-rsin\alpha sin\theta=x_0cos\theta-y_0sin\theta
x=rcos(α+θ)=rcosαcosθ−rsinαsinθ=x0cosθ−y0sinθ
y
=
r
s
i
n
(
α
+
θ
)
=
r
s
i
n
α
c
o
s
θ
+
r
c
o
s
α
s
i
n
θ
=
x
0
s
i
n
θ
+
y
0
c
o
s
θ
y = rsin(\alpha+\theta)=rsin\alpha cos\theta+rcos\alpha sin\theta=x_0sin\theta+y_0cos\theta
y=rsin(α+θ)=rsinαcosθ+rcosαsinθ=x0sinθ+y0cosθ
- cv2.getRotationMatrix2D(center, angle, scale)
- center:图片的旋转中心
- angle:旋转角度
- scale:缩放比例,0.5表示缩小一半,正为逆时针,负为顺时针。
img_rotation = img.copy()
h, w = img_rotation.shape[:2]
M = cv2.getRotationMatrix2D((w/2, h/2), 30, -1)
dst = cv2.warpAffine(img_rotation, M, (2*w, 2*h), borderValue=(25, 255, 255))
cv2.imshow('rotation', dst)
cv2.waitKey(0)
cv2.destroyAllWindows()
仿射变换
仿射变换:平移、旋转、放缩、剪切、反射
- cv2.getAffineTransform(pos1, pos2)
- pos1:变换前的位置
- pos2:变换后的位置
img_affine = img.copy()
h, w = img.shape[:2]
pos1 = np.float32([[50, 50], [200, 50], [50, 200]])
pos2 = np.float32([[10, 100], [200, 50], [100, 250]])
M = cv2.getAffineTransform(pos1, pos2)
print(M)
dst = cv2.warpAffine(img_affine, M, (w, h))
cv2.imshow('dst', dst)
cv2.waitKey(0)
cv2.destroyAllWindows()
透视变换
本质是将图像投影到一个新的平面。
- cv2.getPerspectiveTransfoem(pos1, pos2)
- pos1:透视变换后四个点对应的位置
- pos2:透视变换后四个点对应的位置
- cv2.warpPerspective(src, M, (cols, rows))
- src:原始图像
- M:透视变换矩阵
- (cols, rows):变换后的图像大小,row表示行数,col便是列数
src = img.copy()
rows, cols = src.shape[:2]
pos1 = np.float32([[114, 82], [287, 156], [8, 100], [143, 177]])
pos2 = np.float32([[0, 0], [188, 0], [0, 262], [188, 262]])
M = cv2.getPerspectiveTransform(pos1, pos2)
res = cv2.warpPerspective(src, M, (cols, rows))
cv2.imshow('res', res)
cv2.waitKey(0)