边缘检测算法:Sobel算子、Canny边缘检测、自适应阈值

边缘检测,说白了就是帮我们找到图像中「变化最剧烈」的那些像素点。在车道线场景里,边缘就是车道线与路面之间的分界线。我做了这么多年视觉,可以负责任地告诉你:边缘检测做不好,后面的拟合、跟踪全是白搭。

今天咱们就聊三个最常用的方法:Sobel算子、Canny边缘检测、自适应阈值。它们各有各的脾气,也各有各的坑。

Sobel算子:简单但够用

Sobel算子是最基础的边缘检测方法。它用两个3x3的卷积核,分别计算水平方向和垂直方向的梯度。

水平方向的核长这样:

[-1, 0, 1]
[-2, 0, 2]
[-1, 0, 1]

垂直方向的核:

[-1, -2, -1]
[ 0,  0,  0]
[ 1,  2,  1]

为什么用这两个核?其实就是在做差分的同时,给中心像素更大的权重。我刚开始学的时候也觉得这玩意儿玄乎,后来自己手算一遍就明白了——说白了就是「左边减右边,上面减下面」。

代码实现很简单:

import cv2
import numpy as np

img = cv2.imread('lane.jpg', cv2.IMREAD_GRAYSCALE)

# 计算x方向和y方向的梯度
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_mag = np.sqrt(sobel_x**2 + sobel_y**2)
sobel_mag = np.uint8(np.clip(sobel_mag, 0, 255))
我的经验: Sobel算子对噪声比较敏感。如果图像本身比较干净,比如高速公路上的车道线,Sobel完全够用。但要是遇到雨天、阴影多的场景,建议先做高斯滤波。

Canny边缘检测:工业级标准

Canny算法是我个人最常用的方法。它比Sobel复杂,但效果确实好。整个流程分四步:

  1. 高斯滤波 — 先降噪,避免把噪声当成边缘
  2. 计算梯度 — 用Sobel算梯度幅值和方向
  3. 非极大值抑制 — 只保留梯度方向上的局部最大值
  4. 双阈值检测 — 用高低两个阈值筛选真正的边缘

这里有个关键点:双阈值。高阈值决定哪些是「强边缘」,低阈值决定哪些是「弱边缘」。只有与强边缘相连的弱边缘才会被保留。

代码示例:

# 标准Canny
edges = cv2.Canny(img, 50, 150)

# 如果效果不好,可以试试调整阈值
edges = cv2.Canny(img, 30, 100)  # 更敏感
edges = cv2.Canny(img, 70, 200)  # 更严格
避坑指南: 我曾经在一个项目中,Canny死活检测不出车道线。排查了半天,发现是图像分辨率太高,高斯滤波的核大小没跟着调。记住:图像越大,高斯核也要相应增大。

自适应阈值:应对光照变化

固定阈值的问题很明显——白天和晚上,同一个阈值效果天差地别。自适应阈值就是根据局部区域的像素值动态计算阈值。

OpenCV里实现很简单:

# 自适应阈值
adaptive_thresh = cv2.adaptiveThreshold(
    img, 
    255, 
    cv2.ADAPTIVE_THRESH_GAUSSIAN_C, 
    cv2.THRESH_BINARY, 
    11,  # 邻域大小
    2    # 常数C
)

参数说明:

参数 含义 我的建议
邻域大小 计算阈值的局部窗口大小 奇数,一般11~31之间
常数C 从均值中减去的常数 越大,边缘越少;越小,边缘越多

核心思路: 自适应阈值特别适合光照不均匀的场景。比如隧道入口、树荫下的车道线。我一般会把它和Canny结合使用——先用自适应阈值做二值化,再用Canny找边缘。

三种方法怎么选?

我个人的经验是这样的:

  • Sobel:适合快速验证、实时性要求高的场景。计算量最小。
  • Canny:适合大多数场景,效果稳定。但参数调起来有点烦。
  • 自适应阈值:适合光照变化大的场景。但噪声多的时候效果会变差。

你想想看,实际项目中哪有「一招鲜吃遍天」的事?我通常的做法是:先跑Canny看看效果,如果不行再换自适应阈值。实在不行,就把两种结果做个融合。

一个小技巧: 在车道线检测中,我习惯先做灰度化,然后用高斯滤波(5x5核),最后用Canny。这套组合拳能应对80%的场景。

知识体系图

下面这张图帮你理清三种方法的关系和适用场景:

边缘检测算法对比 Sobel算子 Canny边缘检测 自适应阈值 计算量小 对噪声敏感 适合快速验证 效果稳定 需调双阈值 工业级标准 适应光照变化 噪声多时效果差 需调邻域大小 推荐:Canny + 自适应阈值组合使用,应对复杂场景

嗯,以上就是边缘检测的三个核心方法。记住一点:没有最好的算法,只有最合适的场景。多试、多调、多总结,慢慢你就能找到感觉。

可可精品资料库