Sobel算子是应用广泛的离散微分算子之一,用于图像处理中的边缘检测,计算图像灰度的近似梯度。
基于图像卷积来实现在水平方向和垂直方向检测对应方向上的边缘。
对于源图像与奇数Sobel水平核Gx、垂直核Gy进行卷积可计算水平与垂直变换。
Sobel算子在进行边缘检测时候效率较高,对精度要求不是很高时候,是一种较为常用的边缘检测方法。
Sobel算子对沿着x轴和y轴的排列表示得很好,但是对于其他角度的表示却不够精确,这时候我们可以使用Scharr滤波器。
5.2.1 非极大值一直Sobel检测
步骤1/2/3/4
https://blog.csdn.net/gone_huilin/article/details/53223622
https://bbs.csdn.net/topics/370004267
5.2.2 图像直接卷积实现Sobel
5.2.3 图像卷积下非极大值抑制Sobel
非极大值抑制虽然能够较好剔除虚假边缘点,但对于某些特定场景下的边缘检测并不适用,例如污损文本字符识别。
5.2.4 Sobel库函数实现
1 /////////////////////////////////5.2.4 Sobel库函数实现////////////////////////////// 2 ////////https://blog.csdn.net/gone_huilin/article/details/53223636 3 #include <opencv2/core/core.hpp> 4 #include <opencv2/highgui/highgui.hpp> 5 #include "opencv2/imgproc/imgproc.hpp" 6 #include <iostream> 7 using namespace cv; 8 int main() 9 { 10 cv::Mat srcImage = imread("D:\楼房.jpg"); 11 if (!srcImage.data) 12 return -1; 13 cv::Mat srcGray; 14 cvtColor(srcImage, srcGray, CV_RGB2GRAY); 15 imshow("srcGray", srcGray); 16 // 定义边缘图,水平及垂直 17 cv::Mat edgeMat, edgeXMat, edgeYMat; 18 // 求x方向Sobel边缘 19 Sobel(srcGray, edgeXMat, CV_16S, 1, 0, 3, 1, 20 0, BORDER_DEFAULT); 21 // 求y方向Sobel边缘 22 Sobel(srcGray, edgeYMat, CV_16S, 0, 1, 3, 1, 23 0, BORDER_DEFAULT); 24 // 线性变换转换输入数组元素成8位无符号整型 25 convertScaleAbs(edgeXMat, edgeXMat); 26 convertScaleAbs(edgeYMat, edgeYMat); 27 // x与y方向边缘叠加 28 addWeighted(edgeXMat, 0.5, edgeYMat, 0.5, 0, edgeMat); 29 cv::imshow("edgeYMat", edgeYMat); 30 imshow("edgeMat", edgeMat); 31 // 定义Scharr边缘图像 32 cv::Mat edgeMatS, edgeXMatS, edgeYMatS; 33 // 计算x方向Scharr边缘 34 Scharr(srcGray, edgeXMatS, CV_16S, 1, 0, 1, 35 0, BORDER_DEFAULT); 36 convertScaleAbs(edgeXMatS, edgeXMatS); 37 // 计算y方向Scharr边缘 38 Scharr(srcGray, edgeYMatS, CV_16S, 0, 1, 1, 39 0, BORDER_DEFAULT); 40 // 线性变换转换输入数组元素成8位无符号整型 41 convertScaleAbs(edgeYMatS, edgeYMatS); 42 // x与y方向边缘叠加 43 addWeighted(edgeXMatS, 0.5, edgeYMatS, 0.5, 0, edgeMatS); 44 cv::imshow("edgeMatS", edgeMatS); 45 cv::waitKey(0); 46 return 0; 47 }
5.3 基本边缘检测算子--Laplace
拉普拉斯算子是最简单的各向同性二阶微分算子,具有旋转不变形。
根据微分特性点,该像素点的二阶微分为零的点为边缘点。
图像中奇异点如亮点变得更亮,对于图像中灰度变化剧烈的区域,拉普拉斯算子能实现其边缘检测。其利用二次微分特性与峰值间过零点来确定边缘位置,对奇异点或边界点更加敏感,常应用于图像锐化(突出图像的细节或增强被模糊的图像细节,实现灰度反差增强,使图像变得清晰。积分运算或加权平均让图像变得模糊)工作。
1 ///////////////////////////////////5.2.5 基本边缘检测算子--Laplace////////////////////////////// 2 //////https://blog.csdn.net/Chenyukuai6625/article/details/74784626 3 #include <opencv2/opencv.hpp> 4 #include<opencv2/highgui/highgui.hpp> 5 #include<opencv2/imgproc/imgproc.hpp> 6 7 using namespace cv; 8 9 int main() 10 { 11 //【0】变量的定义 12 Mat src, src_gray, dst, abs_dst; 13 14 //【1】载入原始图 15 src = imread("D:\日光.jpg"); 16 17 //【2】显示原始图 18 imshow("【原始图】图像Laplace变换", src); 19 20 //【3】使用高斯滤波消除噪声 21 GaussianBlur(src, src, Size(3, 3), 0, 0, BORDER_DEFAULT); 22 23 //【4】转换为灰度图 24 cvtColor(src, src_gray, CV_RGB2GRAY); 25 26 //【5】使用Laplace函数 27 Laplacian(src_gray, dst, CV_16S, 3, 1, 0, BORDER_DEFAULT); 28 29 //【6】计算绝对值,并将结果转换成8位 30 convertScaleAbs(dst, abs_dst); 31 32 //【7】显示效果图 33 imshow("【效果图】图像Laplace变换", abs_dst); 34 35 waitKey(0); 36 37 return 0; 38 }
5.4 基本边缘检测算子——Roberts
Roberts算子是利用局部差分寻找边缘的一种算子,是最简单的边缘检测算子。Roberts算子利用对角线方向相邻两像素之差近似梯度赋值来检测边缘,检测垂直边缘的效果要优于其他方向边缘,定位精度高,但对噪声抑制能力较弱。