阅读(2142)
赞(0)
OpenCV Laplace Operator
2017-09-09 11:08:17 更新
目标
在本教程中,您将学习如何:
- 使用OpenCV函数cv :: Laplacian来实现Laplace运算符的离散模拟。
理论
- 在上一个教程中,我们学习了如何使用Sobel操作符。这是基于以下事实:在边缘区域中,像素强度显示“跳跃”或强度的高变化。得到强度的一阶导数,我们观察到边缘的特征是最大值,如图所示:
- 和...如果我们采取二阶导数会发生什么?
您可以观察到二阶导数为零!因此,我们也可以使用此标准来尝试检测图像中的边缘。然而,请注意,零不仅会出现在边缘(它们实际上可以出现在其他无意义的位置); 这可以通过在需要时应用过滤来解决。
Laplace Operator
- 从上面的解释,我们推导出二阶导数可以用来检测边缘。由于图像是“* 2D *”,所以我们需要在两个维度上使用导数。在这里,Laplace Operator很方便。
- Laplace Operator被定义为:
- 拉普拉斯运算符通过函数cv :: Laplacian在OpenCV中实现。事实上,由于拉普拉斯算子使用图像的梯度,所以它在内部调用Sobel算子来执行其计算。
Code
- 这个程序是做什么的?
- 加载图像
- 通过应用高斯模糊来消除噪点,然后将原始图像转换为灰度
- 将Laplace Operator应用于灰度图像并存储输出图像
- 在窗口中显示结果
- 教程代码如下所示。您也可以从这里下载
#include "opencv2/imgproc.hpp"
#include "opencv2/imgcodecs.hpp"
#include "opencv2/highgui.hpp"
using namespace cv;
int main( int argc, char** argv )
{
Mat src, src_gray, dst;
int kernel_size = 3;
int scale = 1;
int delta = 0;
int ddepth = CV_16S;
const char* window_name = "Laplace Demo";
String imageName("../data/lena.jpg"); // by default
if (argc > 1)
{
imageName = argv[1];
}
src = imread( imageName, IMREAD_COLOR ); // Load an image
if( src.empty() )
{ return -1; }
GaussianBlur( src, src, Size(3,3), 0, 0, BORDER_DEFAULT );
cvtColor( src, src_gray, COLOR_BGR2GRAY ); // Convert the image to grayscale
Mat abs_dst;
Laplacian( src_gray, dst, ddepth, kernel_size, scale, delta, BORDER_DEFAULT );
convertScaleAbs( dst, abs_dst );
imshow( window_name, abs_dst );
waitKey(0);
return 0;
}
说明
- 创建一些必需的变量:
Mat src,src_gray,dst;
int kernel_size = 3;
int scale = 1;
int delta = 0;
int ddepth = CV_16S ;
const char * window_name = “Laplace Demo” ;
- 加载源图像:
String imageName("../data/lena.jpg"); // by default
if (argc > 1)
{
imageName = argv[1];
}
src = imread( imageName, IMREAD_COLOR ); // Load an image
if( src.empty() )
{ return -1; }
- 应用高斯模糊来减少噪音:
GaussianBlur( src, src, Size(3,3), 0, 0, BORDER_DEFAULT );
- 使用cv :: cvtColor将图像转换为灰度
cvtColor( src, src_gray, COLOR_BGR2GRAY ); // Convert the image to grayscale
- 将Laplace Operator应用到灰度图像中:
Laplacian( src_gray, dst, ddepth, kernel_size, scale, delta, BORDER_DEFAULT );
其中的论点是:
- src_gray:输入图像。
- dst:目的地(输出)图像
- ddepth:目的地图像的深度。由于我们的输入是CV_8U,我们定义ddepth = CV_16S以避免溢出
- kernel_size:内部应用的Sobel运算符的内核大小。我们在这个例子中使用3。
- 缩放,增量和BORDER_DEFAULT:我们将它们保留为默认值。
- 将Laplace Operator的输出转换为CV_8U图像:
convertScaleAbs(dst,abs_dst);
- 在窗口中显示结果:
imshow(window_name,abs_dst);
waitKey(0);
结果
- 在编译上面的代码之后,我们可以运行它作为参数作为图像的路径。例如,使用作为输入:
- 我们得到以下结果。请注意,如何将树木和牛仔的轮廓定义得很好(除了强度非常相似的区域,即在牛头顶部)。另外,请注意,树木后面的屋顶(右侧)是臭名昭着的。这是因为该地区的对比度较高。