OpenCV 笔记 – 边缘检测(Sobel、Laplace、Canny)


参考文档


一、Sobel 算子


1、简介

Sobel 算子是一个离散的一阶差分算子,用来计算图像亮度函数的一阶梯度近似值。在图像的任何一点使用此算子,将会产生该点对应的梯度矢量或是其法矢量。算子其实是一个模板,用模板与图像做卷积(协相关)运算。

Sobel 模板(x 和y 方向):  
求出近似梯度:
  
梯度方向:
  

2、特点

  • 具有一定的噪声鲁棒性
  • 有边缘方向信息

3、OpenCV 中的 Sobel 函数

函数原型:

void Sobel (InputArray src, OutputArray dst,int ddepth, int dx, int dy, int ksize=3,  double scale=1,  double delta=0,  int borderType=BORDER_DEFAULT);

参数详解:

  • 第一个参数:InputArray 类型的src,为输入图像,填Mat类型即可。

  • 第二个参数:OutputArray类型的dst,即目标图像,函数的输出参数,需要和源图片有一样的尺寸和类型。

  • 第三个参数:int类型的ddepth,输出图像的深度,支持如下src.depth()和ddepth的组合

  • 若src.depth() = CV_8U, 取ddepth =-1/CV_16S/CV_32F/CV_64F

  • 若src.depth() = CV_16U/CV_16S, 取ddepth =-1/CV_32F/CV_64F

  • 若src.depth() = CV_32F, 取ddepth =-1/CV_32F/CV_64F

  • 若src.depth() = CV_64F, 取ddepth = -1/CV_64F

  • 第四个参数:int类型dx,x 方向上的差分阶数。

  • 第五个参数:int类型dy,y方向上的差分阶数。

  • 第六个参数:int类型ksize,有默认值3,表示Sobel核的大小。必须取1,3,5或7。

  • 第七个参数:double类型的scale,计算导数值时可选的缩放因子,默认值是1,表示默认情况下是没有应用缩放的。我们可以在文档中查阅getDerivKernels的相关介绍,来得到这个参数的更多信息。

  • 第八个参数:double类型的delta,表示在结果存入目标图(第二个参数dst)之前可选的delta值,有默认值0。

  • 第九个参数: int类型的borderType,边界模式,默认值为BORDER_DEFAULT。这个参数可以在官方文档中borderInterpolate处得到更详细的信息。

函数使用:

#include <opencv2/opencv.hpp>
using namespace cv;int main()
{Mat grad_x, grad_y;Mat abs_grad_x, abs_grad_y,dst;// 载入原始图  Mat src = imread("1.jpg"); // 显示原始图 imshow("【原始图】sobel边缘检测", src); // 求 X方向梯度Sobel(src, grad_x, CV_16S, 1, 0, 3, 1, 1, BORDER_DEFAULT );convertScaleAbs(grad_x, abs_grad_x );imshow("【效果图】X方向Sobel", abs_grad_x); // 求Y方向梯度Sobel(src, grad_y, CV_16S, 0, 1, 3, 1, 1, BORDER_DEFAULT );convertScaleAbs( grad_y, abs_grad_y );imshow("【效果图】Y方向Sobel", abs_grad_y); // 合并梯度(近似)addWeighted(abs_grad_x, 0.5, abs_grad_y, 0.5, 0, dst );imshow("【效果图】Sobel算子", dst); waitKey(0); return 0;
}

二、Laplace 算子


1、简介

拉普拉斯算子一个二阶微分算子。

Laplace 模板:
  

2、特点

  • 旋转不变性
  • 没有了边缘的方向信息
  • 双倍加强了噪声的影响

3、OpenCV 中的 Sobel 函数

函数原型:

void Laplacian(InputArray src,OutputArray dst,  int ddepth,  int ksize=1,   double scale=1,  double delta=0,  intborderType=BORDER_DEFAULT);

三、Canny 边缘提取


1、特点

检测标准:不丢失重要的边缘,没有虚假的边缘
定位标准:实际边缘与检测到的边缘位置之间的偏差最小
单响应标准:将多个响应降低为单个边缘响应

2、步骤

1) 使用高斯滤波器,以平滑图像,滤除噪声。

2) 计算图像中每个像素点的梯度强度和方向。

可以使用多种边缘检测的算子(如Roberts,Prewitt,Sobel等)返回水平 Gx 和垂直 Gy 方向的一阶导数值,由此便可以确定像素点的梯度G和方向theta 。

3) 应用非极大值(Non-Maximum Suppression)抑制,以消除边缘检测带来的杂散响应。

对图像进行梯度计算后,仅仅基于梯度值提取的边缘仍然很模糊。非极大值抑制则可以帮助将局部最大值之外的所有梯度值抑制为0,对梯度图像中每个像素进行非极大值抑制的算法是:

  • 将当前像素的梯度强度与沿正负梯度方向上的两个像素进行比较。
  • 如果当前像素的梯度强度与另外两个像素相比最大,则该像素点保留为边缘点,否则该像素点将被抑制。

通常为了更加精确的计算,在跨越梯度方向的两个相邻像素之间使用线性插值来得到要比较的像素梯度。

4) 应用双阈值(Double-Threshold)检测来确定真实的和潜在的边缘。

为了解决由于噪声和颜色变化引起的一些边缘像素的杂散响应,必须用弱梯度值过滤边缘像素,并保留具有高梯度值的边缘像素,可以通过选择高低阈值来实现。如果边缘像素的梯度值高于高阈值,则将其标记为强边缘像素;如果边缘像素的梯度值小于高阈值并且大于低阈值,则将其标记为弱边缘像素;如果边缘像素的梯度值小于低阈值,则会被抑制。阈值的选择取决于给定输入图像的内容。

5) 通过抑制孤立的弱边缘最终完成边缘检测。

对于弱边缘像素,因为这些像素可能是从真实边缘提取也可能是因噪声或颜色变化引起的。为了获得准确的结果,应该抑制由后者引起的弱边缘。通常,由真实边缘引起的弱边缘像素将连接到强边缘像素,而噪声响应未连接。为了跟踪边缘连接,通过查看弱边缘像素及其8个邻域像素,只要其中一个为强边缘像素,则该弱边缘点就可以保留为真实的边缘。

3、OpenCV 中 Canny 函数

函数原型:

void Canny(InputArray image, OutputArray edges,  double threshold1,  double threshold2,  int apertureSize=3,  bool L2gradient=false)

参数详解:

  • 第一个参数:InputArray 类型的 image,输入图像,即源图像,填Mat类的对象即可,且需为单通道8位图像
  • 第二个参数:OutputArray 类型的 edges,输出的边缘图,需要和源图片有一样的尺寸和类型
  • 第三个参数:double 类型的 threshold1,第一个滞后性阈值
  • 第四个参数:double 类型的 threshold2,第二个滞后性阈值
  • 第五个参数:int 类型的 apertureSize,表示应用 Sobel 算子的模板大小,默认值3
  • 第六个参数:bool 类型的 L2gradient,一个计算图像梯度幅值的标识,默认值false

函数使用:

#include <opencv2/opencv.hpp>
using namespace cv;int main()
{//载入原始图 Mat src = imread("1.jpg"); //进行Canny边缘检测 Canny(src, src, 150, 100, 3 );//显示边缘检测的结果图imshow("【效果图】Canny边缘检测", src);waitKey(0); return 0;
}

OpenCV 笔记 -- 边缘检测(Sobel、Laplace、Canny)相关推荐

  1. Opencv 笔记5 边缘处理-canny、sobel、Laplacian、Prewitt

    一.边缘检测概述 边缘检测是计算视觉中的基本问题,边缘检测的目的是标识图像中亮度变换明显的点.边缘检测大幅度的减少了图像的数据量(分为两种:灰度图像边缘检测和彩色图像边缘检测),并且剔除了不相关的信息 ...

  2. 2020.11.05 使用OpenCV进行自定义线性滤波 【OpenCV C++ Robert/Sobel/Laplace】

    使用OpenCV进行自定义线性滤波/Robert/Sobel/Laplace 源代码: // testOpencv14.cpp : 此文件包含 "main" 函数.程序执行将在此处 ...

  3. 边缘检测Sobel、Canny、Laplacian

    1.Sobel算子 1.1Sobel 步骤 1.分别在x和y两个方向求导. 2.在图像的每一点,结合以上两个结果求出近似梯度: 1.1.1 分别在x和y两个方向求导. x方向 y方向 1.1.2 在图 ...

  4. OpenCV图像边缘检测(Laplace算法)

    一.Laplace算法简介   二阶微分在亮的一边是负的,在暗的一边是正的.常数部分为零.可以用来确定边的准确位置,以及像素在亮的一侧还是暗的一侧.   拉普拉斯算子是最简单的各向同性微分算子,具有旋 ...

  5. OpenCV学习笔记(十二):边缘检测:Canny(),Sobel(),Laplace(),Scharr滤波器

    OpenCV学习笔记(十二):边缘检测:Canny(),Sobel(),Laplace(),Scharr滤波器 1)滤波:边缘检测的算法主要是基于图像强度的一阶和二阶导数,但导数通常对噪声很敏感,因此 ...

  6. OpenCV边缘检测(Sobel,Scharr,Laplace,Canny)

    对于图像的处理,基本的步骤是这样的: 取得图像数据 -- 将图像进行平滑处理 -- 进行边缘检测,阈值分析 -- 进行形态学的操作 -- 获取某些特征点 -- 分析数据 那么在这里,我就讲解下边缘检测 ...

  7. python+OpenCv笔记(十三):边缘检测——Sobel检测算子

    Sobel检测算子 概述: Sobel边缘检测算法比较简单,实际应用中效率比canny边缘检测效率要高,但是边缘不如Canny检测的准确,但是很多实际应用的场合,sobel边缘却是首选,Sobel算子 ...

  8. sobel边缘检测python_python实现:prewitt, laplace,sobel,scharr, canny, hed

    代码:butub1/Edge-detection​github.com 哭了,实现了的一个赞没有,上面讲理论的一堆赞...................... CatalogFilters Nois ...

  9. OpenCV 笔记(03)— 读取视频、通过摄像头采集视频、采集视频 canny 边缘检测

    我们本节学习如何利用 OpenCV 中的 VideoCapture 类,来对视频进行读取显示,以及调用摄像头. VideoCapture 它提供了从摄像机或视频文件捕获视频的 C++ 接口, 作用是从 ...

最新文章

  1. 全球物联网产业规模不断扩大 中国市场前景分析
  2. 字符串charAt()
  3. MySQL 3.23 中文参考手册
  4. 关于字符串属性的几道面试题目
  5. hdu 4004 二分查找
  6. ielts speaking questions
  7. apex图表使用饼图居中_echarts饼图标题居中以及调整主副标题的间距、字号
  8. MySQL高级 - 常用工具 - mysql
  9. UIview需要知道的一些事情:setNeedsDisplay、setNeedsLayout
  10. 零售业有效利用物联网的几种方法
  11. 【冷笑话】看谁跑的快?
  12. [Sdoi2013] 直径
  13. #QCon#北京2011大会“更有效地做测试”专题Slides资料
  14. 自学指南——零基础教你快速学习软件测试?
  15. 大数据专业python实验报告_大数据导论实验报告
  16. sudo: /usr/bin/sudo must be owned by uid 0 and have the setuid bit set的解决方案(linux)
  17. Linux 解决无法清空回收站问题
  18. 苹果IOS企业开发者账号怎么申请——苹果账号申请记录(未完待续)
  19. 笔记本计算机回收站在哪里,电脑回收站不见了怎么办 四种方法教你快速解决问题【图文教程】...
  20. VFP获取微信小程序用户openID,易如反掌

热门文章

  1. 树和而叉查找树的实现
  2. OC对象的本质及分类
  3. _reincarnation
  4. 修改unity变量名但不丢失序列化值
  5. python 中 for使用小技巧
  6. bzoj2002 [Hnoi2010]Bounce 弹飞绵羊【LCT】
  7. HDU 2055 An easy problem
  8. Python 3基础教程32-正则
  9. 复合数据类型,英文词频统计
  10. 【bzoj1026】[SCOI2009]windy数 数位dp