opencv学习笔记(二十二)拉普拉斯算子cvLaplace()

边缘检测对噪声比较敏感,需要先用高斯滤波器对图像进行平滑。
拉普拉斯对噪声敏感,会产生双边效果。不能检测出边的方向。通常不直接用于边的检测,只起辅助的角色,检测一个像素是在边的亮的一边还是暗的一边利用零跨越,确定边的位置。
OpenCV的拉普拉斯函数实现了拉普拉斯算子的离散模拟。注意,拉普拉斯算子与第5章的拉普拉斯金字塔完全不同。
这里写图片描述
因为拉普拉斯算子可以用二次导数的形式定义,可假设其离散实现类似于二阶Sobel导数。事实的确如此,OpenCV在计算拉普拉斯算子时直接使用Sobel算子。
二阶微分在亮的一边是负的,在暗的一边是正的。常数部分为零。可以用来确定边的准确位置,以及像素在亮的一侧还是暗的一侧。
cvLaplace()函数通常把源图像和目标图像以及中孔大小作为变量。源图像既可以是8位(无符号)图像,也可以是32位(浮点)图像。而目标图像必须是16位(有符号)或者32位(浮点)图像。这里的中孔与Sobel导数中出现的中孔完全一样,事实上主要给出区域大小,在二次求导的计算中,采样这个区域的像素。
拉普拉斯算子可用于各种情况。一个通常的应用是检测“团块”。联想到拉普拉斯算子的形式是沿着X轴和Y轴的二次导数的和,这就意味着周围是更高值的单点或者小块(比中孔小)会将使这个函数值最大化。反过来说,周围是更低值的点将会使函数的负值最大化。
基于这种思想,拉普拉斯算子也可以用作边缘检测。为达此目的,只需要考虑当函数快速变化时其一阶导数变大即可。同样重要的是,当我们逼近类似边缘的不连续地方时导数会快速增长,而穿过这些不连续地方时导数又会快速减小。所以导数会在此范围内有局部极值。这样我们可以期待局部最大值位于二阶导数为0的地方。
原始图像的边缘位于拉普拉斯的值等于0的地方。不幸的是,在拉普拉斯算子中,所有实质性的和没有意义的边缘的检测都是0。但这并不是什么问题,因为我们可以过滤掉这些点,它们的一阶(Sobel)导数值也很大。

cvLaplace()

定义:
void cvLaplace(
const CvArr* src,
CvArr* dst,
int apertureSize=3
);
src
输入图像.

dst
输出图像.

aperture_size
核大小 (与 cvSobel 中定义一样).
对 aperture_size=1 则给出最快计算结果,相当于对图像采用如下内核做卷积:
这里写图片描述
类似于 cvSobel 函数,该函数也不作图像的尺度变换,所支持的输入、输出图像类型的组合和cvSobel一致。

你可能感兴趣的:(opencv学习笔记(二十二)拉普拉斯算子cvLaplace())