计算机视觉入门第一课:核心算法与技术

312次阅读
没有评论

共计 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. 将卷积核在图像上滑动,使其中心位于输入图像的某个像素上
  2. 计算卷积核内所有像素值与相应位置图像像素值的加权和
  3. 将结果赋给中心像素
  4. 重复上述过程,直到遍历整幅图像

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 边缘检测的步骤:

  1. 高斯滤波:平滑图像,减少噪声
  2. 计算梯度:使用 Sobel 算子计算梯度幅值和方向
  3. 非极大值抑制:保留局部最大值,细化边缘
  4. 双阈值检测:确定边缘的强弱,连接边缘

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()

本节小结

在本节中,我们深入探讨了图像处理的核心算法与技术:

  1. 滤波与卷积:理解了卷积运算的原理,掌握了均值滤波、高斯滤波、中值滤波等常见滤波方法
  2. 边缘检测:学习了 Sobel、Canny 等边缘检测算法,理解了它们的工作原理和适用场景
  3. 形态学操作:掌握了腐蚀、膨胀、开运算、闭运算等形态学操作,理解了它们在图像处理中的应用
  4. 阈值分割与二值化:学习了全局阈值、自适应阈值、Otsu 阈值等方法,理解了如何将图像转换为二值图像

这些技术是计算机视觉的基础,是实现图像分割、目标检测、特征提取等高级应用的关键步骤。在实际应用中,这些技术通常会组合使用,例如:

  • 先进行高斯滤波去除噪声
  • 再进行 Canny 边缘检测提取边缘
  • 然后使用形态学操作(如闭运算)连接边缘
  • 最后通过阈值分割确定感兴趣区域

正文完
 0
一诺
版权声明:本站原创文章,由 一诺 于2025-08-03发表,共计5739字。
转载说明:除特殊说明外本站文章皆由CC-4.0协议发布,转载请注明出处。
评论(没有评论)
验证码