3.1 Canny 边缘检测
总目录:1.1 OpenCV介绍与学习路线 | 第三章:边缘、轮廓与几何 | 编号:3.1
← 上一节:2.7 HSV颜色检测 | 下一节:3.2 查找与绘制轮廓 →
3.1 Canny 边缘检测
图像里亮暗变化突然的地方,很可能是物体边界、纹理或阴影。Canny 的工作是把这些变化压成较细、较连续的边缘线。
一、边缘是什么
边缘不是物体本身,而是像素值变化明显的位置:
一整块白纸内部 → 亮度变化小,不像边缘
白纸与黑桌交界 → 亮度突然变化,很像边缘
纸上的纹理、反光 → 也可能产生边缘
所以“有边缘”不等于“找到了目标”。Canny 只是把候选边界提出来,后面还需要 轮廓、几何特征和筛选。
二、Canny 不只是“套两个阈值”
Canny 大致包含:
去噪
↓
计算梯度强度与方向
↓
非极大值抑制,把粗边压细
↓
双阈值分类强边缘与弱边缘
↓
滞后连接:保留与强边缘相连的弱边缘
OpenCV 的 Canny 内部负责后面几步;我们常在调用前自己做轻度高斯滤波。
三、Canny 的函数参数
blurred = cv2.GaussianBlur(gray, (5, 5), 0)
edges = cv2.Canny(blurred, threshold1=50, threshold2=150)
常用参数:
| 参数 | 含义 |
|---|---|
image |
通常是 8 位单通道图像 |
threshold1 |
低阈值 |
threshold2 |
高阈值 |
apertureSize |
Sobel 算子的孔径,默认 3 |
L2gradient |
是否用更精确的 L2 梯度幅值 |
edges = cv2.Canny(gray, 50, 150, apertureSize=3, L2gradient=True)
两个阈值判断的是梯度强度,不是原图像素“比 150 亮还是暗”。
四、双阈值怎样连接边缘
可以把它想成两道关卡:
- 高于高阈值:强边缘,直接保留;
- 低于低阈值:直接丢弃;
- 位于中间:弱边缘,只有与强边缘连通时才保留。
强边缘 ─ 弱边缘 ─ 弱边缘 → 整段可能保留
孤零零的弱边缘 → 丢弃
这样既减少孤立噪声,又能让真实边界较弱的部分接回强边缘。

五、调参顺序与常见误区
推荐顺序
- 先把灰度图和轻度滤波做好;
- 从
(50, 150)之类的宽松起点观察; - 噪声边太多,提高阈值或改善滤波;
- 真边缘断裂,降低阈值或用小核闭运算连接;
- 用多种光照样本验证。
高阈值取低阈值的 2~3 倍只是常见起点,不是 Canny 定律。
自动起点:用中位数估计
median = np.median(gray)
sigma = 0.33
low = int(max(0, (1.0 - sigma) * median))
high = int(min(255, (1.0 + sigma) * median))
edges = cv2.Canny(gray, low, high)
这只是起点,梯度分布和场景变化大时仍要验证。
常见误区
| 现象 | 可能原因 |
|---|---|
| 满屏碎边 | 噪声、纹理、阈值过低 |
| 目标边缘断裂 | 阈值过高、曝光不均、目标本来就模糊 |
| 边缘有两圈 | 物体有内外亮度过渡或线条本身有宽度 |
| 闭运算后全粘住 | 核过大,不是 Canny 本身的问题 |
六、参考
← 上一节:2.7 HSV颜色检测 | 下一节:3.2 查找与绘制轮廓 →
留言区
不收集任何个人信息;昵称只绑定浏览器里的随机 Cookie。