共计 5739 个字符,预计需要花费 15 分钟才能阅读完成。
1. 图像处理基础
1.1 滤波与卷积
1.1.1 滤波原理
滤波是图像处理中最基础的技术之一,通过特定算法对图像像素进行处理,以优化图像质量或提取关键特征。滤波可分为 线性滤波 和非线性滤波 两大类:
- 线性滤波:输出像素是输入邻域像素的加权和,通过卷积运算实现
- 非线性滤波:通过其他数学操作实现,如中值滤波
1.1.2 卷积运算原理
卷积是一种数学运算,通过滑动小窗口(卷积核或滤波器)在输入图像上进行局部区域的乘法运算,然后将这些乘积结果加和起来,形成输出数据。
卷积公式:
$$G(i,j) = \sum_{m=-a}^{a} \sum_{n=-b}^{b} h(m,n) \cdot f(i+m,j+n)$$
其中:
- $$G(i,j)$$ 是输出图像在位置 $(i,j)$ 的像素值
- $$h(m,n)$$ 是卷积核
- $$f(i+m,j+n)$$ 是输入图像在对应位置的像素值
卷积操作步骤:
- 将卷积核在图像上滑动,使其中心位于输入图像的某个像素上
- 计算卷积核内所有像素值与相应位置图像像素值的加权和
- 将结果赋给中心像素
- 重复上述过程,直到遍历整幅图像
1.1.3 常见滤波器类型
| 滤波器类型 | 原理 | 作用 | 适用场景 |
|---|---|---|---|
| 均值滤波 | 取邻域像素的平均值 | 去除随机噪声,使图像平滑 | 低噪声场景,对边缘要求不高 |
| 高斯滤波 | 邻域像素按高斯分布加权平均 | 去除高斯噪声,保留边缘 | 需要保留边缘的场景 |
| 中值滤波 | 邻域像素排序后取中值 | 有效去除椒盐噪声,保留边缘 | 椒盐噪声严重的图像 |
| 拉普拉斯滤波 | 二阶微分运算 | 增强图像边缘 | 图像锐化 |
高斯滤波的数学表达:
$$G(x,y) = \frac{1}{2\pi\sigma^2}e^{-\frac{x^2+y^2}{2\sigma^2}}$$
1.1.4 实战代码示例
import cv2
import numpy as np
import matplotlib.pyplot as plt
# 读取图像
img = cv2.imread('example.jpg')
# 1. 均值滤波
mean_filtered = cv2.blur(img, (5, 5))
# 2. 高斯滤波
gaussian_filtered = cv2.GaussianBlur(img, (5, 5), 0)
# 3. 中值滤波
median_filtered = cv2.medianBlur(img, 5)
# 4. 拉普拉斯滤波
laplacian = cv2.Laplacian(img, cv2.CV_64F)
laplacian = cv2.convertScaleAbs(laplacian)
# 显示结果
plt.figure(figsize=(15, 10))
plt.subplot(2, 3, 1)
plt.imshow(cv2.cvtColor(img, cv2.COLOR_BGR2RGB))
plt.title('Original Image')
plt.axis('off')
plt.subplot(2, 3, 2)
plt.imshow(cv2.cvtColor(mean_filtered, cv2.COLOR_BGR2RGB))
plt.title('Mean Filtered')
plt.axis('off')
plt.subplot(2, 3, 3)
plt.imshow(cv2.cvtColor(gaussian_filtered, cv2.COLOR_BGR2RGB))
plt.title('Gaussian Filtered')
plt.axis('off')
plt.subplot(2, 3, 4)
plt.imshow(cv2.cvtColor(median_filtered, cv2.COLOR_BGR2RGB))
plt.title('Median Filtered')
plt.axis('off')
plt.subplot(2, 3, 5)
plt.imshow(laplacian, cmap='gray')
plt.title('Laplacian Filtered')
plt.axis('off')
plt.tight_layout()
plt.savefig('filtering_comparison.png', dpi=300)
plt.show()
1.2 边缘检测(Canny、Sobel)
1.2.1 边缘检测原理
边缘是图像中颜色、亮度等属性发生突然变化的地方。边缘检测算法通过检测图像中像素的梯度变化来识别边缘。
1.2.2 常用边缘检测算法
| 算法 | 原理 | 优点 | 缺点 |
|---|---|---|---|
| Sobel 算子 | 通过 3 ×3 卷积核计算水平和垂直方向的梯度 | 计算简单,速度快 | 对噪声敏感 |
| Prewitt 算子 | 类似 Sobel,但权重不同 | 计算简单 | 对噪声敏感 |
| Canny 边缘检测 | 多步骤边缘检测:高斯滤波、计算梯度、非极大值抑制、双阈值检测 | 检测准确,抗噪能力强 | 计算较复杂 |
Canny 边缘检测的步骤:
- 高斯滤波:平滑图像,减少噪声
- 计算梯度:使用 Sobel 算子计算梯度幅值和方向
- 非极大值抑制:保留局部最大值,细化边缘
- 双阈值检测:确定边缘的强弱,连接边缘
1.2.3 实战代码示例
import cv2
import matplotlib.pyplot as plt
# 读取图像
img = cv2.imread('example.jpg', 0) # 灰度图像
# 1. Sobel 边缘检测
sobel_x = cv2.Sobel(img, cv2.CV_64F, 1, 0, ksize=3)
sobel_y = cv2.Sobel(img, cv2.CV_64F, 0, 1, ksize=3)
sobel = cv2.sqrt(sobel_x**2 + sobel_y**2)
# 2. Canny 边缘检测
canny = cv2.Canny(img, 100, 200)
# 显示结果
plt.figure(figsize=(15, 10))
plt.subplot(1, 3, 1)
plt.imshow(img, cmap='gray')
plt.title('Original Image')
plt.axis('off')
plt.subplot(1, 3, 2)
plt.imshow(sobel, cmap='gray')
plt.title('Sobel Edge Detection')
plt.axis('off')
plt.subplot(1, 3, 3)
plt.imshow(canny, cmap='gray')
plt.title('Canny Edge Detection')
plt.axis('off')
plt.tight_layout()
plt.savefig('edge_detection_comparison.png', dpi=300)
plt.show()
1.3 形态学操作(膨胀、腐蚀、开闭运算)
1.3.1 形态学操作原理
形态学操作是基于图像形状的数学运算,可以用来改变图像的几何结构和拓扑特性。其核心是使用一个结构元素(通常是一个小的矩阵)与图像进行操作。
1.3.2 常见形态学操作
| 操作 | 原理 | 作用 | 适用场景 |
|---|---|---|---|
| 腐蚀(Erosion) | 结构元素完全包含在图像内部时保留像素,否则置为背景 | 消除小型噪点,分离相连物体,缩小物体 | 去噪,分离物体 |
| 膨胀(Dilation) | 结构元素与图像至少有一个重叠时置为前景 | 填充空洞,连接相近物体,增大物体 | 连接物体,填充空洞 |
| 开运算(Opening) | 先腐蚀后膨胀 | 平滑物体边缘,消除小型物体,分离相连物体 | 去除小噪声,平滑边缘 |
| 闭运算(Closing) | 先膨胀后腐蚀 | 填充孔洞,连接相近物体,消除小型物体 | 填充孔洞,连接物体 |
结构元素:通常为 3 ×3 或 5 ×5 的矩阵,可以是矩形、圆形、十字形等。
1.3.3 实战代码示例
import cv2
import numpy as np
import matplotlib.pyplot as plt
# 生成测试图像(二值图像)img = np.zeros((200, 200), dtype=np.uint8)
cv2.rectangle(img, (50, 50), (150, 150), 255, -1) # 白色矩形
cv2.circle(img, (100, 100), 30, 255, -1) # 白色圆
# 添加一些噪声
for i in range(50):
x = np.random.randint(0, 200)
y = np.random.randint(0, 200)
img[y, x] = 255
# 定义结构元素
kernel = np.ones((5, 5), np.uint8)
# 1. 腐蚀
erosion = cv2.erode(img, kernel, iterations=1)
# 2. 膨胀
dilation = cv2.dilate(img, kernel, iterations=1)
# 3. 开运算
opening = cv2.morphologyEx(img, cv2.MORPH_OPEN, kernel)
# 4. 闭运算
closing = cv2.morphologyEx(img, cv2.MORPH_CLOSE, kernel)
# 显示结果
plt.figure(figsize=(15, 10))
plt.subplot(2, 3, 1)
plt.imshow(img, cmap='gray')
plt.title('Original with Noise')
plt.axis('off')
plt.subplot(2, 3, 2)
plt.imshow(erosion, cmap='gray')
plt.title('Erosion')
plt.axis('off')
plt.subplot(2, 3, 3)
plt.imshow(dilation, cmap='gray')
plt.title('Dilation')
plt.axis('off')
plt.subplot(2, 3, 4)
plt.imshow(opening, cmap='gray')
plt.title('Opening')
plt.axis('off')
plt.subplot(2, 3, 5)
plt.imshow(closing, cmap='gray')
plt.title('Closing')
plt.axis('off')
plt.tight_layout()
plt.savefig('morphology_operations.png', dpi=300)
plt.show()
1.4 阈值分割与二值化
1.4.1 阈值分割原理
阈值分割是将图像转换为二值图像的过程,通过设定一个阈值,将图像中像素值高于阈值的设为前景(白色),低于阈值的设为背景(黑色)。
1.4.2 常见阈值方法
| 方法 | 原理 | 优点 | 缺点 |
|---|---|---|---|
| 全局阈值 | 使用单一阈值 | 简单快速 | 对光照不均匀的图像效果差 |
| 自适应阈值 | 根据局部区域计算阈值 | 适应光照变化 | 计算量较大 |
| Otsu 阈值 | 自动计算最佳阈值,使类间方差最大 | 自动选择阈值,效果好 | 对噪声敏感 |
| 双阈值 | 使用两个阈值,区分强边缘和弱边缘 | 适用于 Canny 边缘检测 | 需要先确定两个阈值 |
Otsu 方法原理:
Otsu 方法通过最大化类间方差来自动确定最佳阈值,将图像分为前景和背景两部分。
1.4.3 实战代码示例
import cv2
import matplotlib.pyplot as plt
# 读取图像
img = cv2.imread('example.jpg', 0) # 灰度图像
# 1. 全局阈值
_, thresh_global = cv2.threshold(img, 127, 255, cv2.THRESH_BINARY)
# 2. 自适应阈值
thresh_adaptive = cv2.adaptiveThreshold(img, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C,
cv2.THRESH_BINARY, 11, 2)
# 3. Otsu 阈值
_, thresh_otsu = cv2.threshold(img, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)
# 4. 双阈值(Canny 边缘检测后的阈值处理)edges = cv2.Canny(img, 50, 150)
_, thresh_double = cv2.threshold(edges, 100, 255, cv2.THRESH_BINARY)
# 显示结果
plt.figure(figsize=(15, 10))
plt.subplot(2, 3, 1)
plt.imshow(img, cmap='gray')
plt.title('Original Image')
plt.axis('off')
plt.subplot(2, 3, 2)
plt.imshow(thresh_global, cmap='gray')
plt.title('Global Thresholding')
plt.axis('off')
plt.subplot(2, 3, 3)
plt.imshow(thresh_adaptive, cmap='gray')
plt.title('Adaptive Thresholding')
plt.axis('off')
plt.subplot(2, 3, 4)
plt.imshow(thresh_otsu, cmap='gray')
plt.title('Otsu Thresholding')
plt.axis('off')
plt.subplot(2, 3, 5)
plt.imshow(thresh_double, cmap='gray')
plt.title('Double Thresholding (Canny)')
plt.axis('off')
plt.tight_layout()
plt.savefig('thresholding_comparison.png', dpi=300)
plt.show()
本节小结
在本节中,我们深入探讨了图像处理的核心算法与技术:
- 滤波与卷积:理解了卷积运算的原理,掌握了均值滤波、高斯滤波、中值滤波等常见滤波方法
- 边缘检测:学习了 Sobel、Canny 等边缘检测算法,理解了它们的工作原理和适用场景
- 形态学操作:掌握了腐蚀、膨胀、开运算、闭运算等形态学操作,理解了它们在图像处理中的应用
- 阈值分割与二值化:学习了全局阈值、自适应阈值、Otsu 阈值等方法,理解了如何将图像转换为二值图像
这些技术是计算机视觉的基础,是实现图像分割、目标检测、特征提取等高级应用的关键步骤。在实际应用中,这些技术通常会组合使用,例如:
- 先进行高斯滤波去除噪声
- 再进行 Canny 边缘检测提取边缘
- 然后使用形态学操作(如闭运算)连接边缘
- 最后通过阈值分割确定感兴趣区域

