edgesCanny 边缘检测

深入理解Canny 边缘检测的原理、实现与应用

Canny 边缘检测

多阶段最优边缘检测算法

  • calendar_today 提出年份: 1986 年
  • person 提出者: John F. Canny
  • category 适用: 边缘检测
  • schedule 复杂度: O(M×N)
  • settings 参数: 低阈值、高阈值、σ
  • memory 空间: O(M×N)

flowchart 算法流程

flowchart LR A[输入图像] --> B[高斯滤波] B --> C[计算梯度] C --> D[非极大值抑制] D --> E[双阈值检测] E --> F[边缘连接] F --> G[输出边缘图]

算法原理

Canny 边缘检测算法由 John F. Canny 在 1986 年提出,旨在找到一个最优的边缘检测算法。Canny 将边缘检测问题转化为一个数学问题,并提出了三个评价边缘检测算法的标准:

target 最优边缘检测三标准
check_circle
低错误率

不漏检、不误检

my_location
定位准确

边缘点接近真实中心

filter_1
单一响应

单边缘单响应

算法步骤详解

sequenceDiagram participant Input as 输入图像 participant Gaussian as 高斯滤波 participant Gradient as 梯度计算 participant NMS as 非极大值抑制 participant Double as 双阈值 participant Edge as 边缘连接 participant Output as 输出 Input->>Gaussian: 5×5 高斯核卷积 Note over Gaussian: 去除噪声#96;σ通常取 1.4 Gaussian->>Gradient: Sobel 算子 Note over Gradient: 计算 Gx, Gy#96;G=sqrt(Gx2+Gy2)#96;theta=arctan(Gy/Gx) Gradient->>NMS: 梯度幅值+方向 Note over NMS: 保留梯度方向#96;上的局部最大值 NMS->>Double: 细化边缘 Note over Double: TL=低阈值#96;TH=高阈值 Double->>Edge: 强/弱边缘分类 Edge->>Output: 滞后阈值处理 Note over Output: 弱边缘连接#96;到强边缘则保留

使用高斯滤波器平滑图像,减少噪声影响。高斯核大小通常为 5×5,标准差σ一般取 1.4。

flowchart LR A[原始图像] --> B[高斯核] B --> C[卷积运算] C --> D[平滑图像] subgraph 高斯核公式 E["G(x,y) = (1/2πσ2)·e^(-(x2+y2)/2σ2)"] end

使用 Sobel 算子计算图像在 x 和 y 方向的梯度,然后计算梯度幅值和方向。

Sobel X 核 Sobel Y 核
[-1  0  1]
[-2  0  2]
[-1  0  1]
[-1 -2 -1]
[ 0  0  0]
[ 1  2  1]

梯度幅值: G = sqrt(Gx2 + Gy2)

flowchart TD A[原始图像] --> B[高斯滤波
去除噪声] B --> C[计算梯度
幅值和方向] C --> D[非极大值抑制
细化边缘] D --> E[双阈值检测
高阈值/低阈值] E --> F{边缘点分类} F -->|梯度>高阈值 | G[强边缘点] F -->|低阈值<梯度<高阈值 | H[弱边缘点] F -->|梯度<低阈值 | I[抑制] G --> J[边缘连接] H --> J J --> K[最终边缘图]
步骤输入输出目的
高斯滤波原始图像平滑图像去除噪声
计算梯度平滑图像梯度图找到边缘候选
非极大值抑制梯度图细化梯度单像素边缘
双阈值细化梯度边缘点连接真实边缘

梯度方向: theta = arctan(Gy/Gx)

沿梯度方向检查像素点,只保留梯度方向上的局部最大值,细化边缘到单像素宽度。

flowchart TD A[梯度方向量化] --> B{4 个方向} B -->|0° | C[水平比较] B -->|45° | D[对角比较↗
↙] B -->|90° | E[垂直比较] B -->|135° | F[对角比较↘
↖] C --> G{是否最大值} D --> G E --> G F --> G G -->|是 | H[保留] G -->|否 | I[抑制为 0]

使用两个阈值区分强边缘、弱边缘和非边缘:

  • 强边缘: 梯度值 > 高阈值 TH,直接接受
  • 弱边缘: 低阈值 TL < 梯度值 ≤ TH,需要进一步判断
  • 非边缘: 梯度值 ≤ TL,直接抑制
info 经验法则: 高阈值通常是低阈值的 2-3 倍

检查弱边缘像素的 8 邻域,如果存在强边缘像素,则将该弱边缘提升为强边缘。

flowchart LR A[弱边缘像素] --> B[检查 8 邻域] B --> C{有强边缘?} C -->|是 | D[提升为强边缘] C -->|否 | E[抑制为 0] style D fill:#e8f5e9 style E fill:#ffebee

analytics 算法可视化

flowchart 算法流程图

flowchart LR A[输入图像] --> B[高斯滤波] B --> C[计算梯度] C --> D[非极大值抑制] D --> E[双阈值] E --> F[边缘连接] F --> G[输出边缘图]

table_chart 参数与特性

参数说明典型值影响
低阈值弱边缘阈值50-100影响边缘连续性
高阈值强边缘阈值100-200影响边缘准确性
高斯核大小去噪程度3 或 5越大去噪越强但细节丢失
梯度方向边缘法线方向0°,45°,90°,135°用于非极大值抑制

Python 实现

算法优缺点

thumb_up 优点
  • check 边缘检测精度高
  • check 对噪声具有较好的鲁棒性
  • check 边缘连续性好
  • check 参数相对较少,易于调节
  • check 理论基础扎实
thumb_down 缺点
  • close 计算复杂度较高
  • close 对参数敏感,需要仔细调节阈值
  • close 可能丢失一些细小的边缘
  • close 对纹理复杂的区域可能出现过度分割

参数调节指南

Canny 边缘检测有两个重要阈值参数:

参数 作用 调节建议 效果
低阈值 TL 低于此值的边缘被忽略 设为高阈值的 1/2 到 1/3 越低,检测到的边缘越多
高阈值 TH 高于此值的边缘被接受 根据图像梯度分布调整 越高,检测到的边缘越少但更可靠
高斯σ 控制平滑程度 通常取 1.0-2.0 越大,去噪越好但边缘越模糊

应用场景

visibility
对象检测

提取物体轮廓用于识别

content_cut
图像分割

作为分割的预处理步骤

local_hospital
医学图像

器官边界提取

factory
工业检测

缺陷检测和尺寸测量

computer
计算机视觉

特征提取预处理

map
特征提取

SLAM 等应用的基础

算法信息卡
  • calendar_today 提出年份: 1986 年
  • person 提出者: John F. Canny
  • category 适用: 边缘检测
  • schedule 时间复杂度: O(M×N)
  • memory 空间复杂度: O(M×N)
  • settings 参数: 低阈值、高阈值、σ