文章目录
前言
在边缘区域,像素强度显示出“跳跃”或强度的高变化。得到强度的一阶导数,我们观察到边缘的特征是最大值,如图所示:
如果我们取二阶导数会发生什么?
您可以观察到二阶导数为零!因此,我们也可以使用这个标准来尝试检测图像中的边缘。但是,请注意,零不仅会出现在边缘(它们实际上可以出现在其他无意义的位置);这可以通过在需要的地方应用过滤来解决。
拉普拉斯算子
从上面的解释,我们推断二阶导数可以用来检测边缘。由于图像是“2D”,我们需要在两个维度上求导。在这里,拉普拉斯算子就派上用场了。
拉普拉斯算子定义为:
一、opencv 函数支持
事实上,由于 Laplacian 使用图像的梯度,它在内部调用Sobel 算子来执行其计算。
1.函数原型:
CV_EXPORTS_W void Laplacian( InputArray src, OutputArray dst, int ddepth,
int ksize = 1, double scale = 1, double delta = 0,
int borderType = BORDER_DEFAULT );
2.参数说明:
src:源图像。
dst:目标图像的大小和频道数与src相同。
ddepth:目标图像的期望深度。
ksize: 用于计算二阶导数滤波器的孔径大小。大小必须是正数和奇数。
scale :可选的计算拉普拉斯值的比例因子。默认情况下,不应用缩放。
delta:可选值,最终结果的偏移值。
测试代码
cv::Mat src;
src = cv::imread("D:\\QtProject\\Opencv_Example\\laplace\\laplace.png", cv::IMREAD_GRAYSCALE);
if (src.empty()) {
cout << "Cannot load image" << endl;
return;
}
cv::imshow("src", src);
// Reduce noise by blurring
cv::GaussianBlur( src, src, cv::Size(5, 5), 3, 3, cv::BORDER_DEFAULT );
cv::Mat dst;
cv::Laplacian(src, dst, CV_16S, 3, 1, 0, cv::BORDER_DEFAULT );
// converting back to CV_8U
cv::Mat abs_dst;
cv::convertScaleAbs( dst, abs_dst );
cv::imshow( "abs_dst", abs_dst );
效果:
参考文章:https://docs.opencv.org/4.x/d5/db5/tutorial_laplace_operator.html