在笔记十四中,我们使用了Sobel算子对图像进行边缘检测,理论依据是像素变化最快的地方最有可能是边缘处,所以使用sobel算子对图像做微分,得到的结果图像当中灰度较大的区域,即为边缘处。
在这里,我们使用Laplace算子来做边缘检测,也是类似的道理,只不过换成了二阶微分,在一阶微分的极大值的地方,二阶微分为零。我们以二阶微分为零的区域作为边缘。当然了一阶微分极小值的地方,即图像变化很慢很慢的地方,二阶微分也可能为零。所以我们还需要进行额外的滤波。
在理论上是这样,但是在实现上,OpenCV使用了类似sobel算子的方法,并且在Laplace算子的运用中,一行二阶微分和列二阶微分的加法结合在一起,用一个kernel计算完毕。
先看看OpenCV当中运用Laplace算子的函数:
void cv::Laplacian( InputArray _src, OutputArray _dst, int ddepth, int ksize, double scale, double delta, int borderType )
使用方式和Sobel相似。
部分实现代码如下:
1 if( ksize == 1 || ksize == 3 ) 2 { 3 float K[2][9] = 4 {{0, 1, 0, 1, -4, 1, 0, 1, 0}, 5 {2, 0, 2, 0, -8, 0, 2, 0, 2}}; 6 Mat kernel(3, 3, CV_32F, K[ksize == 3]); 7 if( scale != 1 ) 8 kernel *= scale; 9 filter2D( src, dst, ddepth, kernel, Point(-1,-1), delta, borderType ); 10 }
OpenCV中使用Laplacian的例子:
1 int main( int, char** argv ) 2 { 3 4 Mat src, src_gray, dst; 5 int kernel_size = 3; 6 int scale = 1; 7 int delta = 0; 8 int ddepth = CV_16S; 9 const char* window_name = "Laplace Demo"; 10 11 /// Load an image 12 src = imread( argv[1] ); 13 14 if( !src.data ) 15 { return -1; } 16 17 /// Remove noise by blurring with a Gaussian filter 18 GaussianBlur( src, src, Size(3,3), 0, 0, BORDER_DEFAULT ); 19 20 /// Convert the image to grayscale 21 cvtColor( src, src_gray, COLOR_RGB2GRAY ); 22 23 /// Create window 24 namedWindow( window_name, WINDOW_AUTOSIZE ); 25 26 /// Apply Laplace function 27 Mat abs_dst; 28 29 Laplacian( src_gray, dst, ddepth, kernel_size, scale, delta, BORDER_DEFAULT ); 30 convertScaleAbs( dst, abs_dst ); 31 32 /// Show what you got 33 imshow( window_name, abs_dst ); 34 35 waitKey(0); 36 37 return 0; 38 }