第3章 图像几何变换
3.1 缩放、平移、旋转
缩放:
python
resized = cv2.resize(img, (width, height)) # 指定尺寸 resized = cv2.resize(img, None, fx=0.5, fy=0.5) # 比例缩放
常用插值方法:cv2.INTER_LINEAR(默认)、cv2.INTER_CUBIC、cv2.INTER_AREA(适合缩小)。
平移:通过构建平移矩阵实现。
python
rows, cols = img.shape[:2] # x 方向平移 50,y 方向平移 100 M = np.float32([[1, 0, 50], [0, 1, 100]]) translated = cv2.warpAffine(img, M, (cols, rows))
旋转:
python
# 获取围绕图像中心的旋转矩阵(角度为正表示逆时针) M = cv2.getRotationMatrix2D((cols/2, rows/2), 45, 1.0) rotated = cv2.warpAffine(img, M, (cols, rows))
3.2 仿射变换与透视变换
仿射变换:平行线保持平行。需要原图中三个不共线的点和目标图中对应的三个点。
python
pts1 = np.float32([[50,50],[200,50],[50,200]]) pts2 = np.float32([[10,100],[200,50],[100,250]]) M = cv2.getAffineTransform(pts1, pts2) affine = cv2.warpAffine(img, M, (cols, rows))
透视变换:任意四边形到矩形的变换。需要四个对应点。
python
pts1 = np.float32([[56,65],[368,52],[28,387],[389,390]]) pts2 = np.float32([[0,0],[300,0],[0,300],[300,300]]) M = cv2.getPerspectiveTransform(pts1, pts2) perspective = cv2.warpPerspective(img, M, (300,300))
透视变换在文档扫描、车牌校正中非常常用。
3.3 图像金字塔
图像金字塔是同一图像不同分辨率的集合,常用于图像融合、特征检测。
- 高斯金字塔:向下采样(缩小)
- 拉普拉斯金字塔:由高斯金字塔计算而得,常用于图像恢复
python
lower_res = cv2.pyrDown(img) # 宽度和高度减半 higher_res = cv2.pyrUp(img) # 宽度和高度加倍
示例:反复执行下采样得到的图像金字塔。
第4章 图像滤波与增强
4.1 平滑滤波
平滑(模糊)可以去除噪声,但也可能丢失边缘细节。
- 均值滤波:简单平均
- 高斯滤波:加权平均,中心权重大,去噪同时保留边缘更多
- 中值滤波:取邻域中值,有效去除椒盐噪声
- 双边滤波:保持边缘的平滑,考虑空间邻近度和像素相似度
python
# 均值滤波 (5x5 核) blur = cv2.blur(img, (5,5)) # 高斯滤波 (核大小必须为正奇数) gaussian = cv2.GaussianBlur(img, (5,5), 0) # 中值滤波 (核大小取奇数) median = cv2.medianBlur(img, 5) # 双边滤波 (直径, sigmaColor, sigmaSpace) bilateral = cv2.bilateralFilter(img, 9, 75, 75)
4.2 边缘检测
边缘是图像中亮度急剧变化的区域。OpenCV 提供了多种边缘检测算子。
- Sobel 算子:计算一阶导数,可指定方向。
- Laplacian 算子:计算二阶导数。
- Canny 边缘检测:最常用的方法,低错误率、良好定位。
python
# Sobel sobelx = cv2.Sobel(img, cv2.CV_64F, 1, 0, ksize=3) # x方向 sobely = cv2.Sobel(img, cv2.CV_64F, 0, 1, ksize=3) # y方向 sobel_absx = cv2.convertScaleAbs(sobelx) # 转为 uint8 sobel_combined = cv2.addWeighted(sobel_absx, 0.5, cv2.convertScaleAbs(sobely), 0.5, 0) # Laplacian laplacian = cv2.Laplacian(img, cv2.CV_64F) laplacian_abs = cv2.convertScaleAbs(laplacian) # Canny(推荐使用灰度图) gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) edges = cv2.Canny(gray, 100, 200) # 阈值1, 阈值2
Canny 中较小的阈值用于边缘连接,较大的阈值用于检测强边缘。通常阈值2是阈值1的2~3倍。
4.3 图像锐化
通过增强高频成分使图像边缘更清晰。可以自定义一个锐化核:
python
kernel = np.array([[0, -1, 0],
[-1, 5,-1],
[0, -1, 0]])
sharpened = cv2.filter2D(img, -1, kernel)
发表回复