1. 图像缩放
缩放是对图像的大小进行调整,即放大或缩小。
cv2.resize(src, dsize, fx, fy, interpolation)
参数:
src 输入图像
dsize 绝对尺寸,直接指定调整后图像的大小
fx,fy 相对尺寸,将dsize设置为None,然后将fx和fy设置为比例因子即可
interpolation 插值方法:
cv.INTER_LINEAR 双线性插值
cv.INTER_NEAREST 最近邻插值
cv.INTER_AREA 像素区域重采样(默认)
cv.INTER_NEAREST 最近邻插值
例1:使用绝对和相对尺寸的方法缩放图片。
图片尺寸374*500
import cv2 as cv
import matplotlib
from matplotlib import pyplot as plt
font = {
"family": "Microsoft YaHei"
}
matplotlib.rc("font", **font)
kids = cv.imread("./image/kids.jpg")
# 获取size
rows, cols = kids.shape[:2]
print(rows, cols)
# 绝对尺寸
res = cv.resize(kids, (2 * cols, 2 * rows))
plt.imshow(res[:, :, ::-1])
plt.title("指定像素放大2倍")
plt.show()
print(res.shape)
# 相对尺寸
res1 = cv.resize(kids, None, fx=0.5, fy=0.5)
plt.imshow(res1[:, :, ::-1])
plt.title("指定像素放大2倍")
plt.show()
print(res1.shape)
输出:
374 500 (748, 1000, 3) (187, 250, 3)
2. 图像平移
将图像按照指定方向和距离,移动到相应的位置。
cv.warpAffine(img, M, dsize)
参数:
img 输入图像
M 2?*?3移动矩阵
dsize 输出图像的大小
输出图像的大小是(宽度, 高度)的形式,width=列数,height=行数。空余部分用黑色填充。
对于(x,y)处的像素点,要把它移动到处时,M矩阵应如下设置:?
? 注意:将M设置为np.float32类型的NumPy数组。
例2:平移图像。
import cv2 as cv
import matplotlib
import numpy as np
from matplotlib import pyplot as plt
font = {
"family": "Microsoft YaHei"
}
matplotlib.rc("font", **font)
kids = cv.imread("./image/kids.jpg")
# 获取size
rows, cols = kids.shape[:2]
# 定义M矩阵
M = np.float32([[1, 0, 100], [0, 1, 50]])
# 移动
res2 = cv.warpAffine(kids, M, (2 * cols, 2 * rows))
plt.imshow(res2[:, :, ::-1])
plt.title("移动")
plt.show()
输出:
3.? 图像旋转
图像旋转指图像按照某个位置转动一定角度的过程,旋转中图像仍保持原始尺寸。图像旋转后图像的水平对称轴、垂直对称轴及中心坐标原点都可能发生变换,因此需要对图像旋转中的坐标进行相应转换。
?图像逆时针旋转θ,则根据坐标转换可得旋转转换为:
其中,
?代入得:
?或者写成旋转矩阵乘法的形式:
同时也要修正原点的位置。原图像中的坐标原点在图像的左上角,经过旋转后图像的大小会有所变化,原点也需要修正。假设在旋转的时候是以旋转中心为坐标原点的,旋转结束后还需要将坐标原点移到图像左上角,也就是还要进行一次变换。
在OpenCV中,图像旋转首先根据旋转角度和旋转中心获取旋转矩阵,然后根据旋转矩阵进行变换,即可实现任意角度和任意中心的旋转效果。?
cv.getRotationMatrix2D(center, angle, scale)
参数:
center 旋转中心
angle 旋转角度
scale 缩放比例
返回值:
旋转矩阵M。
然后,调用cv.warpAffine()完成图像的旋转。
例3:将上述图像逆时针旋转45°。
import cv2 as cv
import matplotlib
from matplotlib import pyplot as plt
font = {
"family": "Microsoft YaHei"
}
matplotlib.rc("font", **font)
kids = cv.imread("./image/kids.jpg")
# 获取size
rows, cols = kids.shape[:2]
# 获取旋转矩阵M
M = cv.getRotationMatrix2D((cols / 2, rows / 2), 45, 0.5)
print(M)
# 旋转
res3 = cv.warpAffine(kids, M, (cols, rows))
plt.imshow(res3[:, :, ::-1])
plt.title("旋转45°")
plt.show()
输出:
[[? 0.35355339?? 0.35355339? 95.49716831] ?[ -0.35355339?? 0.35355339 209.27386361]]
4. 仿射变换
图像的仿射变换涉及到图像的形状位置角度的变化,是深度学习预处理中常到的功能,仿射变换主要是对图像的缩放,旋转,翻转和平移等操作的组合。?
如下图所示,Image 1中的点1, 2 和 3 与Image 2中三个点一一映射, 仍然形成三角形,但形状已经大大改变,通过这样两组三点(感兴趣点)求出仿射变换, 接下来我们就能把仿射变换应用到图像中所有的点中,就完成了图像的仿射变换。
在OpenCV中,仿射变换的矩阵是一个2×3的矩阵:
其中左边的2×2矩阵A是线性变换矩阵,右边的2×1矩阵B是平移项:
对于图像上的任一位置(x,y),仿射变换执行的是如下的操作:
在仿射变换中,原图中所有的平行线在结果图像中同样平行。
cv.getA?neTransform(pts1, pts2)
参数:
从原图像中找到3个点以及他们在输出图像中的位置。
输出:
变换矩阵M。
然后,调用cv.warpAffine()完成图像的仿射变换。
例4:将上述图像进行仿射变换。
import cv2 as cv
import matplotlib
import numpy as np
from matplotlib import pyplot as plt
font = {
"family": "Microsoft YaHei"
}
matplotlib.rc("font", **font)
kids = cv.imread("./image/kids.jpg")
# 获取size
rows, cols = kids.shape[:2]
# 平移,使图像显示完整
M = np.float32([[1, 0, 150], [0, 1, 150]])
# 移动
res4 = cv.warpAffine(kids, M, (cols * 2, rows * 2))
# 原图像中3个点
pts1 = np.float32([[200, 200], [500, 200], [500, 500]])
# 变换后的这3个点
pts2 = np.float32([[200, 200], [600, 200], [700, 500]])
# 获得变换矩阵M
M = cv.getAffineTransform(pts1, pts2)
print(M)
res4 = cv.warpAffine(res4, M, (cols * 2, rows * 2))
plt.imshow(res4[:, :, ::-1])
plt.title("仿射变换")
plt.show()
输出:
[[?? 1.33333333??? 0.33333333 -133.33333333] ?[?? 0.??????????? 1.??????????? 0.??????? ]]
?
5. 透射变换
透射变换是视角变化的结果,是指利用透视中心、像点、目标点三点共线的条件,按透视旋转定律使承影面(透视面)绕迹线(透视轴)旋转某一角度,破坏原有的投影光线束,仍能保持承影面上投影几何图形不变的变换。
?它的本质是将图像投影到一个新的视平面,其通用变换公式为:
?其中,(u,v)是原始的图像像素坐标,w取值为1,(x=x'/z',y=y'/z')是透射变换后的结果。后面的矩阵称为透视变换矩阵,一般情况下,我们将其分为三部分:
其中:T1表示对图像进行线性变换,T2对图像进行平移,T3表示对图像进行投射变换,a22??一般设为1。
cv.getPerspectiveTransform(pts1, pts2)
参数:
从原图像和变换后的图像找到对应的4个点,其中任意三个不共线。
返回值:
变换矩阵T。
然后,调用cv.warpAffine()完成图像的透射变换。?
例5:将上述图像进行透射变换。
import cv2 as cv
import matplotlib
import numpy as np
from matplotlib import pyplot as plt
font = {
"family": "Microsoft YaHei"
}
matplotlib.rc("font", **font)
kids = cv.imread("./image/kids.jpg")
# 获取size
rows, cols = kids.shape[:2]
pst1 = np.float32([[56, 65], [368, 52], [28, 387], [389, 390]])
pst2 = np.float32([[100, 145], [300, 100], [80, 290], [310, 300]])
# 变换矩阵T
T = cv.getPerspectiveTransform(pst1, pst2)
print(T)
res5 = cv.warpPerspective(kids, T, (cols, rows))
plt.imshow(res5[:, :, ::-1])
plt.title("透射变换")
plt.show()
输出:
[[ 3.98327670e-01 -2.09876559e-02? 7.49460064e+01] ?[-1.92233080e-01? 4.29335771e-01? 1.21896057e+02] ?[-7.18774228e-04 -1.33393850e-05? 1.00000000e+00]]
?
6. 图像金字塔
图像金字塔是图像多尺度表达的一种,主要用于图像的分割,是一种以多分辨率来解释图像的有效但概念简单的结构。
图像金字塔用于机器视觉和图像压缩,一幅图像的金字塔是一系列以金字塔形状排列的分辨率逐步降低,且来源于同一张原始图的图像集合。其通过梯次向下采样获得,直到达到某个终止条件才停止采样。金字塔的底部是待处理图像的高分辨率表示,而顶部是低分辨率的近似,层级越高,图像越小,分辨率越低。
cv.pyrUp(img) 对图像进行上采样
cv.pyrDown(img) 对图像进行下采样
例6:将上述图像进行上采样和下采样变换。
import cv2 as cv
import matplotlib
from matplotlib import pyplot as plt
font = {
"family": "Microsoft YaHei"
}
matplotlib.rc("font", **font)
kids = cv.imread("./image/kids.jpg")
# 获取size
rows, cols = kids.shape[:2]
imgup = cv.pyrUp(kids)
plt.imshow(imgup[:, :, ::-1])
plt.title("上采样变换")
plt.show()
imgdown = cv.pyrDown(kids)
plt.imshow(imgdown[:, :, ::-1])
plt.title("下采样变换")
plt.show()
输出:
|