相似性变换
内部方位角度保持不变
旋转:
x
1
⃗
=
R
x
0
⃗
=
[
c
o
s
α
−
s
i
n
α
s
i
n
α
c
o
s
α
]
[
x
0
y
0
]
\vec{x_{1}}=R\vec{x_{0}}=\begin{bmatrix}cos\alpha & -sin\alpha \\ sin\alpha & cos\alpha \end{bmatrix}\begin{bmatrix}x_{0}\\ y_{0}\end{bmatrix}
x1=Rx0=[cosαsinα−sinαcosα][x0y0]
平移:
x
1
⃗
=
R
x
0
⃗
=
[
1
0
t
x
0
1
t
y
]
[
x
0
y
0
]
\vec{x_{1}}=R\vec{x_{0}}=\begin{bmatrix}1 & 0 & t_{x} \\ 0 & 1 & t_{y} \end{bmatrix}\begin{bmatrix}x_{0}\\ y_{0}\end{bmatrix}
x1=Rx0=[1001txty][x0y0]
旋转+平移:
x
1
⃗
=
R
t
x
0
⃗
=
[
c
o
s
α
−
s
i
n
α
t
x
s
i
n
α
c
o
s
α
t
y
]
[
x
0
y
0
1
]
\vec{x_{1}}=Rt\vec{x_{0}}=\begin{bmatrix} cos\alpha & -sin\alpha & t_{x}\\ sin\alpha & cos\alpha & t_{y} \end{bmatrix}\begin{bmatrix} x_{0}\\ y_{0}\\ 1\end{bmatrix}
x1=Rtx0=[cosαsinα−sinαcosαtxty]⎣⎡x0y01⎦⎤
旋转+平移+缩放:
x
1
⃗
=
s
R
t
x
0
⃗
=
s
[
c
o
s
α
−
s
i
n
α
t
x
s
i
n
α
c
o
s
α
t
y
]
[
x
0
y
0
1
]
\vec{x_{1}}=sRt\vec{x_{0}}=s\begin{bmatrix} cos\alpha & -sin\alpha & t_{x}\\ sin\alpha & cos\alpha & t_{y} \end{bmatrix}\begin{bmatrix} x_{0}\\ y_{0}\\ 1\end{bmatrix}
x1=sRtx0=s[cosαsinα−sinαcosαtxty]⎣⎡x0y01⎦⎤
可通过cv.getRotationMatrix2D()获取旋转矩阵,然后再使用cv.warpAffine()完成相似性变换。
import cv2 as cv
import numpy as np
import matplotlib.pyplot as plt
img = cv.imread('lena.jpg')
plt_img = cv.cvtColor(img,cv.COLOR_BGR2RGB)
# 参数:(旋转中心点,旋转角度:逆时针,缩放比例)
rotate_matric = cv.getRotationMatrix2D((plt_img.shape[1]/2, plt_img.shape[0]/2), 30, 1)
tx = 50
ty = 100
transpose_matric = np.float32([[1,0,tx],[0,1,ty]])
# cv.warpAffine
# 参数:(待操作的图像,操作矩阵,输出图像尺寸)
img_rotate = cv.warpAffine(plt_img,rotate_matric,(plt_img.shape[1],plt_img.shape[0]))
img_transpose = cv.warpAffine(plt_img,transpose_matric,(plt_img.shape[1],plt_img.shape[0]))
plt.figure(figsize=(12,6))
plt.subplot(1,3,1)
plt.title('src image')
plt.imshow(plt_img)
plt.subplot(1,3,2)
plt.title('rotate image')
plt.imshow(img_rotate)
plt.subplot(1,3,3)
plt.title('transpose image')
plt.imshow(img_transpose)
plt.show()
放射变换
保留内部平行关系。
矩阵A由原图中的三个点坐标与变形后的图像中的三个点坐标构成。
x
1
⃗
=
A
x
0
⃗
=
[
a
b
c
d
e
f
]
[
x
0
y
0
1
]
\vec{x_{1}}=A\vec{x_{0}}=\begin{bmatrix} a & b & c\\ d & e & f \end{bmatrix}\begin{bmatrix} x_{0}\\ y_{0}\\ 1\end{bmatrix}
x1=Ax0=[adbecf]⎣⎡x0y01⎦⎤
可通过cv.getAffineTransform()获取旋转矩阵,然后再使用cv.warpAffine()完成相似性变换。
import cv2 as cv
import numpy as np
# 将平行四边形转换为矩形
# 读入平行四边形图像
img = cv.imread('affine_src.png')
plt_img = cv.cvtColor(img,cv.COLOR_BGR2RGB)
# 分别从原图和目标图中选取三个不共线的坐标点,用于生成仿射变换的矩阵
src_points = np.float32([[28, 77]
, [213, 29]
, [121,232]])
# 计算映射后的长和宽
res_width = int(np.sqrt((src_points[1][0]-src_points[0][0])**2+(src_points[1][1]-src_points[0][1])**2))
res_height = int(np.sqrt((src_points[2][0]-src_points[0][0])**2+(src_points[2][1]-src_points[0][1])**2))
# 点顺序:左上,左下,右上
dst_points = np.float32([[0, 0], [res_height-1,0], [0,res_width-1]])
affine_matric = cv.getAffineTransform(src_points,dst_points)
img_affine = cv.warpAffine(plt_img, affine_matric, (res_height, res_width))
plt.figure(figsize=(10,6))
plt.subplot(1,2,1)
plt.title('src image')
plt.imshow(plt_img)
plt.subplot(1,2,2)
plt.title('affine transformation image')
plt.imshow(img_affine)
plt.show()
投影变换
内部角度关系也不保留,仅保留相邻关系。
矩阵P由原图中的四个点坐标与变形后的图像中的四个点坐标构成。
x
1
⃗
=
P
x
0
⃗
=
[
a
b
c
d
e
f
g
h
i
]
[
x
0
y
0
z
0
]
\vec{x_{1}}=P\vec{x_{0}}=\begin{bmatrix} a & b & c\\ d & e & f\\ g & h & i \end{bmatrix}\begin{bmatrix} x_{0}\\ y_{0}\\ z_{0}\end{bmatrix}
x1=Px0=⎣⎡adgbehcfi⎦⎤⎣⎡x0y0z0⎦⎤
import cv2 as cv
import numpy as np
img = cv.imread('timg.jpg')
cols, rows, channels = img.shape
# 分别从原图和目标图中选取四个不共线的坐标点,用于生成投影变换的矩阵
src_points = np.float32([[239, 345], [406, 345], [165, 449], [470, 449]])
dst_points = np.float32([[0, 0], [270, 0], [0, 120], [270, 120]])
perspect_matric = cv.getPerspectiveTransform(src_points,dst_points)
img_perspect = cv.warpPerspective(img, perspect_matric, (270, 120))
cv.imshow('src image', img)
cv.imshow('perspect image', img_perspect)
cv.waitKey(0)
img_perspect = cv.warpPerspective(img, perspect_matric, (270, 120))
cv.imshow('src image', img)
cv.imshow('perspect image', img_perspect)
cv.waitKey(0)
借助上述的几种不同的图像变换操作、像素操作以及gamma校正等,可以将少量的图像数据集进行augmentation。