阅读(2187) (11)

OpenCV Laplace Operator

2017-09-09 11:08:17 更新

目标

在本教程中,您将学习如何:

  • 使用OpenCV函数cv :: Laplacian来实现Laplace运算符的离散模拟。

理论

  • 在上一个教程中,我们学习了如何使用Sobel操作符。这是基于以下事实:在边缘区域中,像素强度显示“跳跃”或强度的高变化。得到强度的一阶导数,我们观察到边缘的特征是最大值,如图所示:

Laplace Operator

  • 和...如果我们采取二阶导数会发生什么?

Laplace Operator

您可以观察到二阶导数为零!因此,我们也可以使用此标准来尝试检测图像中的边缘。然而,请注意,零不仅会出现在边缘(它们实际上可以出现在其他无意义的位置); 这可以通过在需要时应用过滤来解决。

Laplace Operator

  • 从上面的解释,我们推导出二阶导数可以用来检测边缘。由于图像是“* 2D *”,所以我们需要在两个维度上使用导数。在这里,Laplace Operator很方便。
  • Laplace Operator被定义为:

Laplace Operator算法

  • 拉普拉斯运算符通过函数cv :: Laplacian在OpenCV中实现。事实上,由于拉普拉斯算子使用图像的梯度,所以它在内部调用Sobel算子来执行其计算。

Code

  • 这个程序是做什么的?
  1. 加载图像
  2. 通过应用高斯模糊来消除噪点,然后将原始图像转换为灰度
  3. 将Laplace Operator应用于灰度图像并存储输出图像
  4. 在窗口中显示结果
  • 教程代码如下所示。您也可以从这里下载
#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 );
  cvtColor( src, src_gray, COLOR_BGR2GRAY ); // Convert the image to grayscale
  • 将Laplace Operator应用到灰度图像中:
  Laplacian( src_gray, dst, ddepth, kernel_size, scale, delta, BORDER_DEFAULT );

其中的论点是:

  1. src_gray:输入图像。
  2. dst:目的地(输出)图像
  3. ddepth:目的地图像的深度。由于我们的输入是CV_8U,我们定义ddepth = CV_16S以避免溢出
  4. kernel_size:内部应用的Sobel运算符的内核大小。我们在这个例子中使用3。
  5. 缩放,增量和BORDER_DEFAULT:我们将它们保留为默认值。
  • 将Laplace Operator的输出转换为CV_8U图像:
  convertScaleAbs(dst,abs_dst);
  • 在窗口中显示结果:
  imshow(window_name,abs_dst);
  waitKey(0);

结果

  • 在编译上面的代码之后,我们可以运行它作为参数作为图像的路径。例如,使用作为输入:

Laplace Operator

  • 我们得到以下结果。请注意,如何将树木和牛仔的轮廓定义得很好(除了强度非常相似的区域,即在牛头顶部)。另外,请注意,树木后面的屋顶(右侧)是臭名昭着的。这是因为该地区的对比度较高。

Laplace Operator