图像的边缘是图像的基本特征,边缘点是灰度阶跃变化的像素点,即灰度值的导数较大或极大的地方,边缘检测是图像识别的第一步。用图像的一阶微分和二阶微分来加强图像的灰度跳变,而边缘也就是灰度变化的地方。所以,这些传统的一阶微分算子如Robert、Sobel、prewitt等,以及二阶微分算子Laplacian等等本质上都是能够用于检测边缘的。这些算子均可以称为边缘检测算子。html
边缘检测能够大幅度的减小数据量,剔除那些不相关的信息,保留图像重要的结构属性,通常的边缘检测的步骤有:算法
1)滤波编程
边缘检测主要基于图像的一阶和二阶微分,可是导数、微分对噪声很敏感,梯度计算容易受噪声影响,所以须要用滤波来抑制噪声。函数
2)加强学习
为了检测边界,须要肯定邻域中灰度变化,加强边缘的基础是肯定图像各点邻域强度的变化值,利用锐化突出了灰度变化的区域。spa
3)检测code
通过加强的图像,邻域中不少点的梯度值比较大,可是并非全部点都是边缘点,须要采用某种方法来取舍,通常使用阈值来划分图像各点。orm
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著
3、Sobel边缘检测
http://www.javashuo.com/article/p-qjryyhcc-bg.html
4、学习笔记-canny边缘检测
https://www.cnblgs.com/mmmmc/p/10524640.html
我的博客,转载请注明。