1 //-----------------------------------【头文件包含部分】---------------------------------------
2 // 描述:包含程序所依赖的头文件
3 //----------------------------------------------------------------------------------------------
4 #include <opencv2/opencv.hpp>
5 #include<opencv2/highgui/highgui.hpp>
6 #include<opencv2/imgproc/imgproc.hpp>
7
8 //-----------------------------------【命名空间声明部分】---------------------------------------
9 // 描述:包含程序所使用的命名空间
10 //-----------------------------------------------------------------------------------------------
11 using namespace cv;
12 //-----------------------------------【main( )函数】--------------------------------------------
13 // 描述:控制台应用程序的入口函数,我们的程序从这里开始
14 //-----------------------------------------------------------------------------------------------
15 int main( )
16 {
17 //【0】创建 grad_x 和 grad_y 矩阵
18 Mat grad_x, grad_y;
19 Mat abs_grad_x, abs_grad_y,dst;
20
21 //【1】载入原始图
22 Mat src = imread("1.jpg"); //工程目录下应该有一张名为1.jpg的素材图
23
24 //【2】显示原始图
25 imshow("【原始图】sobel边缘检测", src);
26
27 //【3】求 X方向梯度
28 Sobel( src, grad_x, CV_16S, 1, 0, 3, 1, 1, BORDER_DEFAULT );
29 convertScaleAbs( grad_x, abs_grad_x );
30 imshow("【效果图】 X方向Sobel", abs_grad_x);
31
32 //【4】求Y方向梯度
33 Sobel( src, grad_y, CV_16S, 0, 1, 3, 1, 1, BORDER_DEFAULT );
34 convertScaleAbs( grad_y, abs_grad_y );
35 imshow("【效果图】Y方向Sobel", abs_grad_y);
36
37 //【5】合并梯度(近似)
38 addWeighted( abs_grad_x, 0.5, abs_grad_y, 0.5, 0, dst );
39 imshow("【效果图】整体方向Sobel", dst);
40
41 waitKey(0);
42 return 0;
43 }
Sobel 算子是一个主要用作边缘检测的离散微分算子 (discrete differentiation operator)。它Sobel算子结合了高斯平滑和微分求导,用来计算图像灰度函数的近似梯度。在图像的任何一点使用此算子,将会产生对应的梯度矢量或是其法矢量。
sobel算子的计算过程:
我们假设被作用图像为 I.然后进行如下的操作:
1.分别在x和y两个方向求导。
①水平变化: 将 I 与一个奇数大小的内核Gx进行卷积。比如,当内核大小为3时, Gx的计算结果为:
②垂直变化: 将: I 与一个奇数大小的内核Gy进行卷积。比如,当内核大小为3时, Gx的计算结果为:
2.在图像的每一点,结合以上两个结果求出近似梯度:
另外有时,也可用下面更简单公式代替:
。
如果梯度G大于某一阈值,则认为该点(x,y)为边缘点。
原始图像:
边缘检测后的图像: