OpenCV3入门(八)图像边缘检测

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 = 3,
                         double scale = 1, double delta = 0,
                         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, 1, 0, 3, 1, 1, BORDER_DEFAULT);
convertScaleAbs(imgX, imgX);
imshow("X方向Sobel", imgX);

//Y方向梯度
Sobel(img, imgY, CV_8U, 0, 1, 3, 1, 1, BORDER_DEFAULT);
convertScaleAbs(imgY, imgY);
imshow("Y方向Sobel", imgY);

//合并梯度(近似)
addWeighted(imgX, 0.5, imgY, 0.5, 0, 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(5, 5), 0, 0);
imshow("高斯图", img2);
Laplacian(img2, img3, CV_8U, 3, 1, 0);
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 = 3, bool L2gradient = false );

示例如下:

img = imread("D:\\WORK\\5.OpenCV\\LeanOpenCV\\pic_src\\pic7.bmp", IMREAD_GRAYSCALE);
imshow("原图", img);
Canny(img, img2, 3, 9, 3);
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

原文地址:https://www.cnblogs.com/pingwen/p/12324348.html

时间: 2024-08-29 18:50:59

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

AppleWatch开发入门八——Watch中图片缓存的处理

AppleWatch开发入门八--Watch中图片缓存的处理 由于iWatch在存储和性能上都和iPhone有着很大的差距,这就要求开发者对程序有更高的性能优化,下载与传输图像,在Watch操作中是一个非时的过程,因此,watchOS中为我们提供了一个缓存图片的框架,并且接口和使用都非常简单. WatchOS中缓存图片的方法封装在WKInterfaceDevice这个类中,其中添加图片进入缓存的方法如下: //添加一个UIImage对象进入缓存目录,设置name,当我们设置图片时,可以直接通过n

基于matlab的经典图像边缘检测算法

图像边缘检测算法 (1)Robert算子边缘检测 (2)Sobel算子边缘检测 (3)Prewitt算子边缘检测 (4)LOG算子边缘检测 (5)Canny边缘检测 Matlab的实现. 其实还只是掉包侠,一点算法没有写 争取有空用openCV写一遍 I=imread('1.jpg'); I0=rgb2gray(I); subplot(231); imshow(I); BW1=edge(I0,'Roberts',0.16); subplot(232); imshow(BW1); title('R

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

图像边缘检测--OpenCV之cvCanny函数 分类: C/C++ void cvCanny( const CvArr* image, CvArr* edges, double threshold1, double threshold2, int aperture_size=3 ); image单通道输入图像.edges单通道存储边缘的输出图像threshold1第一个阈值threshold2第二个阈值aperture_sizeSobel 算子内核大小 (见 cvSobel). 函数 cvCa

OpenCV使用Sobel滤波器实现图像边缘检测

纯粹阅读,请移步OpenCV使用Sobel滤波器实现图像边缘检测 效果图 源码 KqwOpenCVFeaturesDemo Sobel滤波器也叫Sobel算子,与Canny边缘检测一样,需要计算像素的灰度梯度,只不过是换用另一种方式. 使用Sobel算子计算边缘的步骤 将图像转为灰度图像 // 原图置灰 Imgproc.cvtColor(src, grayMat, Imgproc.COLOR_BGR2GRAY); 计算水平方向灰度梯度的绝对值 Imgproc.Sobel(grayMat, gra

OpenCV使用Canny边缘检测器实现图像边缘检测

纯粹阅读,请移步OpenCV使用Canny边缘检测器实现图像边缘检测 效果图 源码 KqwOpenCVFeaturesDemo Canny边缘检测器是一种被广泛使用的算法,并被认为是边缘检测最优的算法,该方法使用了比高斯差分算法更复杂的技巧,如多向灰度梯度和滞后阈值化. Canny边缘检测器算法基本步骤 平滑图像:通过使用合适的模糊半径执行高斯模糊来减少图像内的噪声. 计算图像的梯度:这里计算图像的梯度,并将梯度分类为垂直.水平和斜对角.这一步的输出用于在下一步中计算真正的边缘. 非最大值抑制:

[WebGL入门]八,着色器的说明和基础

注:文章译自http://wgld.org/,原作者杉本雅広(doxas),文章中如果有我的额外说明,我会加上[lufy:],另外,鄙人webgl研究还不够深入,一些专业词语,如果翻译有误,欢迎大家指正. 认识GLSL WebGL是无法利用固定渲染管线的,这个在之前的文章(四,渲染准备)里已经简单的说明过了.所以,代替它的是可编辑渲染管线中的一种着色语言,叫做GLSL(OpenGL Shading Language). 是用来在OpenGL中着色编程的语言,GLSL使用C语言为基础,并且有自己独

OpenCV高斯差分技术实现图像边缘检测

纯粹阅读,请移步OpenCV高斯差分技术实现图像边缘检测 效果图 源码 KqwOpenCVFeaturesDemo 边缘是图像中像素亮度变化明显的点. 高斯差分算法步骤 将图像转为灰度图像 // 原图置灰 Imgproc.cvtColor(src, grayMat, Imgproc.COLOR_BGR2GRAY); 用两个不同的模糊半径对灰度图像执行高斯模糊(取得两幅高斯模糊图像) // 以两个不同的模糊半径对图像做模糊处理 Imgproc.GaussianBlur(grayMat, blur1

C#基础入门 八

C#基础入门 八 泛型 C#中的泛型能够将类型作为参数来传递,即在创建类型时用一个特定的符号,如"T"来作为一个占位符,代替实际的类型,等待实例化时用一个实际的类型来代替. public class Test<T> { public void Swap(T a,T b) { } } 使用泛型类型可以最大限度的重用代码.保护类型的安全以及提高性能 降低了强制转换或装箱操作的成本或风险.可以对泛型进行约束以访问特定数据类型的方法 实例化:Test<int> test

OpenCV3入门(六)图像滤波

1.图像滤波理论 1.1图像滤波理论 图像滤波即在尽量保留图像细节特征的条件下对目标图像的噪声进行抑制,是图像预处理中不可缺少的操作.消除图像中的噪声又叫做图像滤波或平滑,滤波的目的有两个,一是突出特征以方便处理,二是抑制噪声. 空间域滤波就是在图像平面上对像素进行操作.空间域滤波大体分为两类:平滑.锐化. 平滑滤波:模糊处理,用于减小噪声,实际上是低通滤波,典型的滤波器是高斯滤波. 锐化滤波:提取边缘突出边缘及细节.弥补平滑滤波造成的边缘模糊.实际上是高通滤波. 空间域处理可由下式表示: g(