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

1、边缘检测基础

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

边缘检测能够大幅度的减小数据量,剔除那些不相关的信息,保留图像重要的结构属性,通常的边缘检测的步骤有:算法

1)滤波编程

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

2)加强学习

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

3)检测code

通过加强的图像,邻域中不少点的梯度值比较大,可是并非全部点都是边缘点,须要采用某种方法来取舍,通常使用阈值来划分图像各点。orm

2、边缘检测算子

2.1一阶微分算子htm

1)原理blog

图像的边缘就是图像灰度发生快速变化的地方。对于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

3Sobel边缘检测

http://www.javashuo.com/article/p-qjryyhcc-bg.html

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

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

 

我的博客,转载请注明。

http://www.javashuo.com/article/p-guuwmfyp-gx.html

相关文章
相关标签/搜索