> 技术文档 > 图像边缘检测

图像边缘检测

目录

一.图像边缘检测

1.图像边缘检测概述

2.Sobel算子原理与实现

3.Scharr算子

4.Laplacian算子

5.Canny边缘检测(重点)

6.效果对比


一.图像边缘检测

1.图像边缘检测概述

2.Sobel算子原理与实现

代码是实现步骤:

  • 边缘检测是图像处理和计算机视觉中的重要工具,用于检测数字图像中的明显变化、边缘或不连续区域。
  • 主要方法包括:Sobel算子、scharr算子,Laplacian算子、Canny算子等。
  • Sobel算子结合高斯平滑和微分求导,通过局部差分计算梯度近似值。
  • 包含两组3x3矩阵(横向和纵向模板),分别用于水平和垂直方向的边缘检测。
  • 横向检测:用右边像素值减去左边像素值;纵向检测:用下方像素值减去上方像素值。
  • 检测时需分步进行(先横向后纵向),避免同时设置dx=1dy=1导致结果不理想(线条过细且存在空洞)。
  • 横向检测
    • 使用cv2.Sobel(),设置dx=1dy=0,数据类型为cv2.CV_64F以保存负数梯度值。
    • 对结果取绝对值(cv2.convertScaleAbs)将负数转为正数显示。
  • 纵向检测
    • 设置dx=0dy=1,同样使用cv2.CV_64F并取绝对值。
  • 融合结果:通过图像加权融合(cv2.addWeighted)将横向和纵向检测结果合并,填补空洞。
import cv2#1.sobel算子yuan=cv2.imread(\'img.png\',0)cv2.imshow(\'yuan\',yuan)cv2.waitKey(0)#x方向上的边缘yuan_x=cv2.Sobel(yuan,-1,dx=1,dy=0)#信息范围(0~255)cv2.imshow(\'yuan_x\',yuan_x)cv2.waitKey(0)yuan_x_64=cv2.Sobel(yuan,cv2.CV_64F,dx=1,dy=0)#信息范围(-1020~1020)cv2.imshow(\'yuan_x_64\',yuan_x_64)cv2.waitKey(0)#x方向上的边缘含负数信息无法显示,所以进行取绝对值操作yuan_x_full=cv2.convertScaleAbs(yuan_x_64)cv2.imshow(\'yuan_x_full\',yuan_x_full)cv2.waitKey(0)#y方向上的边缘yuan_y_64=cv2.Sobel(yuan,cv2.CV_64F,dx=0,dy=1)#信息范围(-1020~1020)cv2.imshow(\'yuan_y_64\',yuan_y_64)cv2.waitKey(0)yuan_y_full=cv2.convertScaleAbs(yuan_y_64)cv2.imshow(\'yuan_y_full\',yuan_y_full)cv2.waitKey(0)#图像加权运算组合yuan_xy_full=cv2.addWeighted(yuan_x_full,1,yuan_y_full,1,0)cv2.imshow(\'yuan_xy_full\',yuan_xy_full)cv2.waitKey(0)cv2.destroyAllWindows()

注意事项:

  • 输入图像需先转换为灰度图。
  • 避免直接使用unit8数据类型(会丢失负数梯度信息),推荐使用cv2.CV_64F
  • 分步检测后融合的效果优于同时设置dx=1dy=1

3.Scharr算子

  • 改进:中心权重更大(中间为10,四角为3),精度更高,但线条更密集(可能包含更多伪边缘)。
  • 代码实现:仅需将Sobel算子中的cv2.Sobel改为cv2.Scharr
#2.scharr算子img=cv2.imread(\'img.png\',0)cv2.imshow(\'img\',img)cv2.waitKey(0)img_x_64 = cv2.Scharr(img,cv2.CV_64F,dx=1,dy=0)img_x_full=cv2.convertScaleAbs(img_x_64)img_y_64 = cv2.Scharr(img,cv2.CV_64F,dx=0,dy=1)img_y_full=cv2.convertScaleAbs(img_y_64)img_xy_full=cv2.addWeighted(img_x_full,1,img_y_full,1,0)cv2.imshow(\'img_xy_full\',img_xy_full)cv2.waitKey(0)

4.Laplacian算子

  • 特点:不区分方向(直接计算变化率),卷积核中心为-4,四周为1,无需分步融合。
  • 代码:cv2.Laplacian + 取绝对值,步骤更简单,但效果较粗糙(线条断续、颜色淡)。
    img=cv2.imread(\'img.png\',0)img_lap=cv2.Laplacian(img,cv2.CV_64F)img_lap_full=cv2.convertScaleAbs(img_lap)cv2.imshow(\'img_lap_full\',img_lap_full)cv2.waitKey(0)

5.Canny边缘检测(重点)

  • 原理
    1. 高斯降噪:去除噪声干扰。
    2. 梯度计算:通过Sobel算子计算梯度幅值和方向(像素变化最剧烈的方向)。
    3. 非极大值抑制:保留梯度方向上最亮的点,抑制其他点。
    4. 双阈值筛选
      • 高阈值(如150):强边缘(保留)。
      • 低阈值(如100):弱边缘(若与强边缘连接则保留,否则剔除)。
  • 代码实现
    #4.canny算子img=cv2.imread(\'img.png\',0)img_canny=cv2.Canny(img,120,180)img_canny_full=cv2.convertScaleAbs(img_canny)cv2.imshow(\'img_canny_full\',img_canny_full)cv2.waitKey(0)cv2.destroyAllWindows()
  • 优势

边缘更细、更真实(避免伪边缘)。

背景干净(纯黑),仅保留显著轮廓。

  • 参数调整:阈值过高可能导致边缘断裂,过低则噪声增多。

6.效果对比

  • Sobel/Scharr:检测较多细节(如花纹),但可能包含非边缘信息。
  • Laplacian:线条较淡,连续性差。
  • Canny:仅保留强边缘(如人物轮廓),背景纯净,适合