1、边缘检测基础

图像的边缘是图像的基本特征,边缘点是灰度阶跃变化的像素点,即灰度值的导数较大或极大的地方,边缘检测是图像识别的第一步。用图像的一阶微分和二阶微分来增强图像的灰度跳变,而边缘也就是灰度变化的地方。因此,这些传统的一阶微分算子如Robert、Sobel、prewitt等,以及二阶微分算子Laplacian等等本质上都是可以用于检测边缘的。这些算子都可以称为边缘检测算子。

边缘检测可以大幅度的减少数据量,剔除那些不相关的信息,保留图像重要的结构属性,一般的边缘检测的步骤有:

1)滤波

边缘检测主要基于图像的一阶和二阶微分,但是导数、微分对噪声很敏感,梯度计算容易受噪声影响,因此需要用滤波来抑制噪声。

2)增强

为了检测边界,需要确定邻域中灰度变化,增强边缘的基础是确定图像各点邻域强度的变化值,利用锐化突出了灰度变化的区域。

3)检测

经过增强的图像,邻域中很多点的梯度值比较大,但是并不是所有点都是边缘点,需要采用某种方法来取舍,一般使用阈值来划分图像各点。

2、边缘检测算子

2.1一阶微分算子

1)原理

图像的边缘就是图像灰度发生快速变化的地方。对于f(t),其导数f'(t)反映了每一处的变化趋势,在变化最快的位置其导数最大,sobel算子的思路就是模拟求一阶导数。

其中:

梯度的方向就是函数f(x,y)最大变化率的方向。梯度的幅值作为最大变化率大小的度量,值为:

离散的二维函数f(i,j),可以用有限差分作为梯度的一个近似值。

为了简化计算,可以用绝对值来近似。

|▽f(i,j)|= |f(i+1,j)-f(i,j)| +|f(i,j+1)-f(i,j)|

2)Sobel算子

Sobel算子是离散微分算子(discrete differentiation operator),用来计算图像灰度的近似梯度,梯度越大越有可能是边缘,Sobel集合了高斯平滑和微分求导,又被称为一阶微分算子、求导算子,在水平和垂直两个方向上求导,得到的是图像在X方法与Y方向梯度图像。

函数原型:

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

示例代码:

img = imread("D:\\WORK\\5.OpenCV\\LeanOpenCV\\pic_src\\pic7.bmp", IMREAD_GRAYSCALE);
imshow("原图", img); //X方向梯度
Sobel(img, imgX, CV_8U, , , , , , BORDER_DEFAULT);
convertScaleAbs(imgX, imgX);
imshow("X方向Sobel", imgX); //Y方向梯度
Sobel(img, imgY, CV_8U, , , , , , BORDER_DEFAULT);
convertScaleAbs(imgY, imgY);
imshow("Y方向Sobel", imgY); //合并梯度(近似)
addWeighted(imgX, 0.5, imgY, 0.5, , img2);
imshow("整体方向Sobel", img2);

输出结果为:

2.2二阶微分算子

1)原理

二维函数f(x,y)在二阶微分(拉普拉斯算子)的定义为:

将上式相加后就得到拉普拉斯算子:

对应的滤波模板如下:

考虑到求绝对值计算梯度,正负系数图形的响应一样,上面的模板也可以表示为:

上面的模板具有对称性,所以求一次滤波就可以,不需要像一阶微分那样计算2次。

2)应用

拉普拉斯算子是二阶微分算子,对噪声敏感,Laplace算子对孤立象素的响应要比对边缘或线的响应要更强烈,因此只适用于无噪声图象。存在噪声情况下,使用Laplacian算子检测边缘之前需要先进行低通滤波。高斯-拉普拉斯算子,又称LoG算子,就是为了补充这种缺陷被创立的,它先进行高斯低通滤波,然后再进行拉普拉斯二阶微分锐化。

示例如下。

img = imread("D:\\WORK\\5.OpenCV\\LeanOpenCV\\pic_src\\pic7.bmp", IMREAD_GRAYSCALE);
imshow("原图", img);
GaussianBlur(img, img2, Size(, ), , );
imshow("高斯图", img2);
Laplacian(img2, img3, CV_8U, , , );
imshow("Laplacian图", img3);

输出结果为:

2.3 Canny算子

1)原理

在图像边缘检测中,抑制噪声和边缘精准定位是无法同时满足的,一些边缘检测算法通过平滑滤波去除噪声的同时,也增加了边缘检测的不确定性,而提高边缘检测算子对边缘的敏感性的同时,也提高了对噪声的敏感性。Canny算子力图在抗噪声干扰和精准定位之间寻求最佳折中方案。

Canny算法主要有4个步骤:

  • 用高斯滤波器来平滑图像;
  • 用一介偏导的有限差分来计算梯度的幅值和方向;
  • 对梯度进行非极大值抑制,保留极大值,抑制其他值;
  • 用双阈值算法检测和连接边缘。

2)应用

函数原型为:

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

示例如下:

img = imread("D:\\WORK\\5.OpenCV\\LeanOpenCV\\pic_src\\pic7.bmp", IMREAD_GRAYSCALE);
imshow("原图", img);
Canny(img, img2, , , );
imshow("canny", img2);

输出效果如下图。

修改阈值之后,Canny(img, img2, 45, 90, 3);效果如下图。

3、参考文献

1、《OpenCV3 编程入门》,电子工业出版社,毛星雨著

2、《学习OpenCV》,清华大学出版社,Gary Bradski, Adrian kaehler著

3、Sobel边缘检测

https://www.cnblogs.com/yibeimingyue/p/10878514.html

4、学习笔记-canny边缘检测

https://www.cnblgs.com/mmmmc/p/10524640.html

个人博客,转载请注明。

https://www.cnblogs.com/pingwen/p/12324348.html

OpenCV3入门(八)图像边缘检测的更多相关文章

  1. 图像边缘检测——几种图像边缘检测算子的学习及python 实现

    本文学习利用python学习边缘检测的滤波器,首先读入的图片代码如下: import cv2 from pylab import * saber = cv2.imread("construc ...

  2. CSharpGL(24)用ComputeShader实现一个简单的图像边缘检测功能

    CSharpGL(24)用ComputeShader实现一个简单的图像边缘检测功能 效果图 这是红宝书里的例子,在这个例子中,下述功能全部登场,因此这个例子可作为使用Compute Shader的典型 ...

  3. 图像边缘检测--OpenCV之cvCanny函数

    图像边缘检测--OpenCV之cvCanny函数 分类: C/C++ void cvCanny( const CvArr* image, CvArr* edges, double threshold1 ...

  4. Python实现图像边缘检测算法

    title: "Python实现图像边缘检测算法" date: 2018-06-12T17:06:53+08:00 tags: ["图形学"] categori ...

  5. 网络编程懒人入门(八):手把手教你写基于TCP的Socket长连接

    本文原作者:“水晶虾饺”,原文由“玉刚说”写作平台提供写作赞助,原文版权归“玉刚说”微信公众号所有,即时通讯网收录时有改动. 1.引言 好多小白初次接触即时通讯(比如:IM或者消息推送应用)时,总是不 ...

  6. C#基础入门 八

    C#基础入门 八 泛型 C#中的泛型能够将类型作为参数来传递,即在创建类型时用一个特定的符号,如"T"来作为一个占位符,代替实际的类型,等待实例化时用一个实际的类型来代替. pub ...

  7. cesium编程入门(八)设置材质

    cesium编程入门(八)设置材质 Cesium中为几何形状设置材质有多种方法 第一种方法 Material 直接构建Cesium.Material对象,通过设置Material的属性来进行控制,官方 ...

  8. 14图像边缘检测的sobel_ctrl控制模块

    一设计功能 计算得到的dxy,再通过和阈值比较大小,输出po_sum作为VGA的输入,在显示器器上显示图像的轮廓. 二设计思路 根据前一篇博客对sobel算法的介绍,先通过FIFO的双流水线操作采集到 ...

  9. OpenCV3入门(十)图像轮廓

    1.图像轮廓 1.1图像轮廓与API函数 轮廓是一系列相连的点组成的曲线,代表了物体的基本外形,相对于边缘,轮廓是连续的,边缘并不全部连续.一般地,获取图像轮廓要经过下面几个步骤: 1)     读取 ...

随机推荐

  1. javaScript类型和对象

    javaScript基本数据类型 Undefined: Null: Boolean: String: Number: Symbol: Object. 注意 JavaScript 的代码 undefin ...

  2. iOS滤镜系列-滤镜开发概览

    概述 滤镜最早的出现应该是应用在相机镜头前实现自然光过滤和调色的镜片,然而在软件开发中更多的指的是软件滤镜,是对镜头滤镜的模拟实现.当然这种方式更加方便快捷,缺点自然就是无法还原拍摄时的真实场景,例如 ...

  3. ArcEngine连接Oracle数据库

    问题1: 最近写服务需要用ArcEngine连接Oracle数据库,以前连接数据库都会弹出一个窗体.然后填好之后就可以连接了,这样很麻烦. 代码如下: private bool ConnectToSd ...

  4. FileUpload的控件上传excel

    在一个使用FileUpload的控件上传excel,读取excel的数据 因为上传的路径一直被限定在C:\Program\IIS\Express 一直限制这个文件下, 想要解决这个问题. 在谷歌浏览器 ...

  5. ASP.NET 开源导入导出库Magicodes.IE 导出Pdf教程

    基础教程之导出Pdf收据 说明 本教程主要说明如何使用Magicodes.IE.Pdf完成Pdf收据导出 要点 导出PDF数据 自定义PDF模板 导出单据 如何批量导出单据 导出特性 PdfExpor ...

  6. Java中SMB的应用

    目录 SMB 服务操作 Ⅰ SMB简介 Ⅱ SMB配置 2.1 Windows SMB Ⅲ 添加SMB依赖 Ⅳ 路径格式 Ⅴ 操作共享 Ⅵ 登录验证 SMB 服务操作 Ⅰ SMB简介 ​ SMB(全称 ...

  7. python练习题-9-6

    本代码是<Python核心编程(第二版)>第九章的9-6练习题,完成的功能为:文件比较:比较两个文本文件是否相同,如果不同,给出第一个不同处的行号和列号. #!/usr/bin/env p ...

  8. JUC中的原子操作类及其原理

    昨天简单的看了看Unsafe的使用,今天我们看看JUC中的原子类是怎么使用Unsafe的,以及分析一下其中的原理! 一.简单使用AtomicLong 还记的上一篇博客中我们使用了volatile关键字 ...

  9. 运用路由约束 使用属性路由 精通ASP-NET-MVC-5-弗瑞曼

  10. openjudge 拯救公主

    点击打开题目 看到这道题,第一感觉是我有一句m2p不知当讲不当讲 传送门就算了,你提莫还来宝石,还不给我每种最多有几个~~ 在一般的迷宫问题里,无论已经走了多少步,只要到达同一个点,状态便是等价的,但 ...