公司动态

计算机视觉基础|第8章 图像边缘检测

📅 2026/8/7 8:10:16
计算机视觉基础|第8章 图像边缘检测
目录前言8.1 本章学习目标8.2 前置理论8.2.1 什么是边缘8.2.2 为什么要先滤波8.2.3 基础公共代码原图灰度图8.3 Sobel 算子8.4 Scharr 算子---Sobel 增强版8.5 Laplacian 拉普拉斯算子8.6 Canny 边缘检测 ---重要8.7 四种边缘检测算子对比表8.8 新手高频坑点8.9 本章小结前言承接第 7 章图像滤波。边缘就是图像像素发生剧烈突变的位置代表物体轮廓边界。边缘检测可以把物体轮廓提取出来是图像分割、目标检测的前置步骤。8.1 本章学习目标理解边缘检测底层原理图像梯度掌握 Sobel 算子、Scharr 算子、Laplacian 拉普拉斯算子重点掌握 Canny 边缘检测理解阈值、高斯降噪对边缘检测的影响能够对比不同算子的输出效果8.2 前置理论8.2.1 什么是边缘图像中像素灰度值快速跳变的地方就是边缘。比如物体和背景交界灰度从 0 直接跳到 255。数学上用梯度描述灰度变化快慢梯度越大灰度变化越剧烈越有可能是边缘。8.2.2 为什么要先滤波图像噪声会产生很多虚假边缘。边缘检测之前一般先做高斯滤波降噪把噪点抹平减少伪边缘。处理流程原图 → 高斯滤波降噪 → 边缘检测算子 → 输出边缘图像8.2.3 基础公共代码原图import cv2 import numpy as np #读取图片边缘检测一般使用灰度图 img cv2.imread(rD:\pythoncode2\bigdata_ai40\Image\girl.png) img cv2.resize(img,(500,500)) gray cv2.cvtColor(img,cv2.COLOR_BGR2GRAY) cv2.imshow(gray,gray) cv2.waitKey(0)灰度图8.3 Sobel 算子Sobel 算子是一种离散的微分算子该算子结合了高斯平滑和微分求导运算。该算子利用局部差分寻找边缘计算所得的是一个梯度的近似值。Sobel算子包含2组3×3的矩阵分别为横向和纵向模板将之与图像作平面卷积即可分别得出横向及纵向的亮度差分近似值。Sobel 算子分别计算水平梯度X 方向、竖直梯度Y 方向。X 方向 Sobel检测竖直边缘左右灰度变化Y 方向 Sobel检测水平边缘上下灰度变化cv2.Sobel(src, ddepth, dx, dy, ksize)ddepth输出图像深度一般写cv2.CV_64F允许存负数梯度有正有负dx1,dy0计算 x 方向梯度dx0,dy1计算 y 方向梯度ksize算子核大小常用 3注意梯度会出现负值。OpenCV 会自动截断负数变成 0丢失一部分边缘所以先使用CV_64F保存正负再用cv2.convertScaleAbs()取绝对值。# Sobel算子 # X方向梯度检测竖直边缘 sobel_x cv2.Sobel(gray, cv2.CV_64F, dx1, dy0, ksize3) sobel_x_abs cv2.convertScaleAbs(sobel_x) #Y方向梯度检测水平边缘 sobel_y cv2.Sobel(gray, cv2.CV_64F, dx0, dy1, ksize3) sobel_y_abs cv2.convertScaleAbs(sobel_y) #合并x、y两个方向的边缘 sobel_merge cv2.addWeighted(sobel_x_abs,0.5,sobel_y_abs,0.5,0) cv2.imshow(Sobel‑X 竖直边缘,sobel_x_abs) cv2.imshow(Sobel‑Y 水平边缘,sobel_y_abs) cv2.imshow(Sobel合并全边缘,sobel_merge) cv2.waitKey(0)8.4 Scharr 算子---Sobel 增强版原理Scharr算子是Sobel算子的优化增强版本OpenCV 提供独立原生函数cv2.Scharr()无需嵌套 Sobel 使用。该算子优化了卷积核权重放大梯度差值对微弱、细碎、浅淡的灰度变化更敏感能够提取 Sobel 无法识别的细边缘细节更丰富。核心语法cv2.Scharr(src, ddepth, dx, dy)src输入灰度图像ddepth图像深度固定使用cv2.CV_64F保存正负梯度dx1, dy0求取 X 方向梯度检测竖直边缘dx0, dy1求取 Y 方向梯度检测水平边缘固定特性Scharr 算子内核尺寸固定为 3×3不支持自定义核大小检测方向规则仅支持单方向求导只能 dx1/dy0 或 dx0/dy1不能同时为1梯度处理规则算子运算会产生正负梯度OpenCV 默认截断负值丢失边缘必须用cv2.CV_64F接收再通过cv2.convertScaleAbs()取绝对值还原完整边缘固定内核内置固定 3×3 高精度权重核无法自定义尺寸是轻量化高精度边缘算子示例代码# Scharr算子 # X方向梯度检测竖直边缘 scharr_x cv2.Scharr(gray, cv2.CV_64F, dx1, dy0) scharr_x_abs cv2.convertScaleAbs(scharr_x) #Y方向梯度检测水平边缘 scharr_y cv2.Scharr(gray, cv2.CV_64F, dx0, dy1) scharr_y_abs cv2.convertScaleAbs(scharr_y) #加权融合双向边缘得到完整轮廓 scharr_merge cv2.addWeighted(scharr_x_abs, 0.5, scharr_y_abs, 0.5, 0) #展示结果 cv2.imshow(Scharr-X , scharr_x_abs) cv2.imshow(Scharr-Y , scharr_y_abs) cv2.imshow(Scharr , scharr_merge) cv2.waitKey(0)Scharr与Sobel算子核心对比Sobel核权重小适合梯度变化明显的强边缘抗噪相对好一点。Scharr核权重更大能捕捉微弱细边缘缺点对噪声更敏感更容易提取伪边缘。8.5 Laplacian 拉普拉斯算子拉普拉斯算子计算二阶导数可以同时捕捉 X、Y 两个方向边缘对灰度变化更敏感。缺点对噪声非常敏感必须提前降噪。# Laplacian拉普拉斯算子 lap cv2.Laplacian(gray,cv2.CV_64F,ksize3) lap_abs cv2.convertScaleAbs(lap) cv2.imshow(Laplacian,lap_abs) cv2.waitKey(0)8.6 Canny 边缘检测 ---重要Canny 是效果最好的边缘检测算法内部一共 4 步内部自动做高斯滤波消除噪声计算图像梯度得到梯度大小、梯度方向非极大值抑制把粗的边缘线条 “压细”只保留局部梯度最大值边缘变细双阈值筛选高阈值、低阈值大于高阈值确定是边缘保留小于低阈值直接丢弃不是边缘介于两者中间只有和确定边缘相连才保留否则丢弃# Canny边缘检测 # cv2.Canny(输入灰度图,低阈值,高阈值) canny_img cv2.Canny(gray, threshold150, threshold2150) cv2.imshow(Canny,canny_img) cv2.waitKey(0) cv2.destroyAllWindows()参数经验高低阈值比例一般维持 1:2 ~ 1:3阈值调大边缘变少很多弱边缘丢失阈值调小边缘变多会出现很多噪声伪边缘8.7 四种边缘检测算子对比表算子函数特点缺点Sobelcv2.Sobel(ksize3)分开提取水平 / 竖直边缘抗噪尚可对微弱边缘不敏感边缘线条较粗Scharrcv2.Sobel(ksizecv2.SCHARR)Sobel 增强捕捉微弱细边缘对噪声敏感容易出现伪边缘Laplaciancv2.Laplacian()同时检测 xy 双方向二阶导数对噪声极其敏感Cannycv2.Canny()内部降噪 非极大抑制 双阈值输出细而干净边缘需要手动调试双阈值8.8 新手高频坑点Sobel、Scharr、Laplacian 一定要设置cv2.CV_64F再convertScaleAbs()取绝对值否则丢失一半边缘。Laplacian、Scharr 对噪声敏感使用前建议手动高斯滤波。Canny 输入是灰度图像不要直接传入彩色图。Canny 阈值需要调试阈值过大丢失边缘阈值过小噪声大量混入。Sobel/Scharr 不要直接写dx1,dy1效果很差分开求 x、y 再addWeighted合并。8.9 本章小结边缘本质是灰度梯度突变。Sobel 适合强边缘Scharr 是 Sobel 增强捕捉微弱边缘但更容易受噪声干扰。Laplacian 二阶导数对噪声敏感。Canny 是工业最常用边缘检测内部完成高斯降噪、非极大值抑制、双阈值筛选输出干净细边缘。