理论
-
在上一个教程中,我们学习了如何使用Sobel算子。这是基于以下事实:在边缘区域中,像素强度显示出“跳跃”或强度的高度变化。获得强度的一阶导数,我们观察到边缘的特征是最大值,如图中所示:
-
那么.....如果我们采用二阶导数会发生什么?
您可以观察到二阶导数为零!因此,我们也可以使用此标准来尝试检测图像中的边缘。但请注意,零不仅会出现在边缘(它们实际上可能出现在其他无意义的位置); 这可以通过在需要时应用过滤来解决。
拉普拉斯算子
- 从上面的解释,我们推断出二阶导数可用于检测边缘。由于图像是“ 2D ”,我们需要在两个维度上采用导数。拉普拉斯算子在这里很方便。
- 的拉普拉斯算子被定义为:
- Laplacian算子由OpenCV函数Laplacian实现。实际上,由于拉普拉斯算子使用图像的梯度,因此它在内部调用Sobel算子来执行其计算。
说明
-
创建一些所需的变量:
Mat src, src_gray, dst; int kernel_size = 3; int scale = 1; int delta = 0; int ddepth = CV_16S; char* window_name = "Laplace Demo";
-
加载源图像:
src = imread( argv[1] ); if( !src.data ) { return -1; }
-
应用高斯模糊来减少噪音:
GaussianBlur( src, src, Size(3,3), 0, 0, BORDER_DEFAULT );
-
使用cvtColor将图像转换为灰度
cvtColor( src, src_gray, CV_BGR2GRAY );
-
将拉普拉斯算子应用于灰度图像:
Laplacian( src_gray, dst, ddepth, kernel_size, scale, delta, BORDER_DEFAULT );
参数在哪里:
- src_gray:输入图像。
- dst:目标(输出)图像
- ddepth:目标图像的深度。由于我们的输入是CV_8U,我们定义ddepth = CV_16S以避免溢出
- kernel_size:要在内部应用的Sobel运算符的内核大小。我们在这个例子中使用3。
- scale,delta和BORDER_DEFAULT:我们将它们保留为默认值。
-
将拉普拉斯算子的输出转换为CV_8U图像:
convertScaleAbs( dst, abs_dst );
-
在窗口中显示结果:
imshow( window_name, abs_dst );