基于Canny算子的图像边缘检测系统
项目介绍
本项目是一个基于MATLAB环境开发的图像处理系统,旨在从数字图像中精确地提取边缘轮廓。系统核心算法采用经典的Canny边缘检测算子,这是一种多阶段的算法,能够有效检测广泛的边缘特性。该项目不仅调用了MATLAB的基础矩阵运算功能,还手动实现了Canny算法的各个核心步骤(如高斯核生成、非极大值抑制、双阈值滞后处理等),展示了完整的边缘检测底层逻辑。
该系统特别适合用于展示图像结构信息,通过精确的滤波、梯度计算和细化处理,最终输出单像素宽度的清晰二值化边缘图像。
主要功能特性
- 鲁棒的图像读取机制:系统优先读取内置测试图像,若读取失败,能够自动生成基于正弦/余弦波函数的合成图像进行测试,保证程序在任何环境下均可运行。
- 完整的算法流水线:实现了从彩色转灰度、高斯滤波平滑、Sobel梯度计算、非极大值抑制到滞后阈值处理的标准Canny全流程。
- 自适应加权灰度转换:不直接调用工具箱转换函数,而是采用标准的亮度加权公式将RGB转换为灰度。
- 手动核生成与卷积:根据设定的Sigma值和核大小动态生成高斯卷积核,而非使用预设模板。
- 方向量化的非极大值抑制:基于梯度方向将边缘分为四个主要方向(水平、垂直、两个对角线)进行细化,有效剔除模糊边缘。
- 双阈值与边缘连接(滞后处理):采用强弱双阈值策略,并通过栈(Stack)结构的迭代算法实现边缘连接,避免了递归调用可能导致的溢出问题。
- 全过程可视化:在一个窗口内分块显示原始图像、高斯平滑图、梯度幅值图、NMS结果、最终边缘图以及原图与结果的融合对比图,便于分析每一步的处理效果。
系统要求
- MATLAB R2016a 或更高版本(代码中使用了
imfuse 和 conv2 等基础函数)。 - Image Processing Toolbox(仅用于辅助显示和读取,核心算法逻辑为原生实现)。
算法实现细节与逻辑分析
本项目的主程序文件 main.m 包含一个主入口函数和多个底层辅助函数,具体实现逻辑如下:
1. 图像预处理与环境初始化
程序启动时首先清理工作区。在图像读取阶段,系统尝试加载
peppers.png。如果文件不存在,系统通过
meshgrid 和三角函数生成一张包含平滑波纹的合成图像。随后,利用加权平均法(R:0.2989, G:0.5870, B:0.1140)将图像转换为双精度灰度图,为后续数值计算奠定基础。
2. 高斯滤波平滑 (Gaussian Smoothing)
为了抑制高频噪声对梯度计算的影响,代码中定义了
kernelSize = 5 (5x5窗口) 和
sigma = 1.4。
- 核心逻辑:通过自定义函数依据高斯分布公式 $e^{-(x^2+y^2)/(2sigma^2)}$ 生成高斯核,并进行归一化处理确保核系数之和为1。
- 卷积操作:使用了零填充(Zero Padding)处理图像边界,并利用MATLAB内置的高效
conv2 函数进行卷积运算,得到平滑后的图像。
3. 梯度计算 (Sobel Gradient)
在平滑图像的基础上,利用Sobel算子检测边缘强度和方向。
- 算子定义:分别定义了X方向和Y方向的3x3 Sobel卷积核。
- 计算过程:分别对图像进行卷积得到水平梯度 $G_x$ 和垂直梯度 $G_y$。
- 幅值与方向:
* 梯度幅值通过欧几里得距离公式 $sqrt{G_x^2 + G_y^2}$ 计算。
* 梯度方向由
atan2 函数计算,并转换为角度制,用于后续的非极大值抑制。
4. 非极大值抑制 (Non-Maximum Suppression, NMS)
这是细化边缘的关键步骤,目的是将宽边缘变为单像素宽的锐利边缘。
- 方向量化:将每个像素点的梯度方向(归一化到0-180度)量化为四个主要方向:0度(水平)、45度(对角)、90度(垂直)、135度(反对角)。
- 抑制逻辑:对于每个像素,检查其在梯度方向上的两个邻域像素(例如,若梯度方向为0度,则比较左右相邻像素)。如果当前像素的梯度幅值不是这三个点中的最大值,则将其幅值置为0(抑制);否则保留。
5. 双阈值检测与边缘连接 (Hysteresis Thresholding)
最后一步通过双阈值算法确定最终边缘,去伪存真。
- 阈值设定:定义了相对比例,高阈值为最大梯度的0.15倍,低阈值为高阈值的0.05倍。
- 分类:
*
强边缘(大于高阈值):直接确认为边缘(赋值255)。
*
弱边缘(介于两者之间):暂定为候选边缘(赋值25)。
*
非边缘(低于低阈值):直接剔除(赋值0)。
- 边缘连接(滞后):采用8连通域分析。代码使用了一个显式的栈结构(Stack)来追踪强边缘。对于每一个强边缘点,检查其8个邻域像素,如果邻域中有弱边缘点,则将该弱边缘升级为强边缘,并将其加入栈中继续搜索。这一过程迭代进行,直到没有新的弱边缘可以被连接。未被连接的弱边缘最终被丢弃。
6. 结果输出
最终生成的二值图像中,1表示边缘,0表示背景。程序通过
subplot 将六个阶段的图像(原图、平滑、梯度、NMS、最终结果、融合对比)展示在同一窗口中,直观体现算法各步骤的作用。
使用方法
- 将代码保存为
main.m 文件。 - 确保MATLAB当前工作路径包含该文件。
- 在MATLAB命令行窗口输入
main 并回车。 - 等待程序运行,系统将弹出一个图形窗口显示处理流程和最终的边缘检测结果。