前面介绍了Sobel等几种一阶导数图像边缘检测算子,图像通过与这些算子的卷积计算可以提取出图像边缘信息。但是在利用一阶导数的边缘检测算子进行边缘检测时,有时会出现因检测到的边缘点过多而导致边缘(线)过粗的情况。
通过去除一阶导数中的非局部最大值就可以检测出更细的边缘,而一阶导数的局部最大值对应着二阶导数的零交叉点。所以通过找图像的二阶导数的零交叉点就能找到精确的边缘点。二阶导数可以通过快速的图像像素值强度的变化来检测图像边缘,其检测原理跟一阶导数有点类似,只是二阶导数计算的是图像 x , y x,y x,y 两个方向的二阶导数。
与梯度方法类似,用于图像锐化和图像边缘检测的Laplacian算子的概念也是相同的。Laplacian算子是一种无方向性的二阶导数算子,其在点 ( x + y ) (x+y) (x+y)处的拉普拉斯值定义为:
(1) ∇ 2 f = ∂ 2 f ∂ x 2 + ∂ 2 f ∂ y 2 \nabla^2f=\frac {\partial^2 f}{\partial x^2 }+\frac {\partial^2 f}{\partial y^2 }\tag{1} ∇2f=∂x2∂2f+∂y2∂2f(1)
其中:
(2) ∂ 2 f ∂ x 2 = f ( i + 1 , j ) − 2 f ( i , j ) + f ( i − 1 , j ) \frac {\partial^2 f}{\partial x^2 } = f(i+1,j)-2f(i,j)+f(i-1,j)\tag{2} ∂x2∂2f=f(i+1,j)−2f(i,j)+f(i−1,j)(2)
(3) ∂ 2 f ∂ y 2 = f ( i , j + 1 ) − 2 f ( i , j ) + f ( i , j − 1 ) \frac {\partial^2 f}{\partial y^2 } = f(i,j+1)-2f(i,j)+f(i,j-1)\tag{3} ∂y2∂2f=f(i,j+1)−2f(i,j)+f(i,j−1)(3)
合并式 ( 2 ) (2) (2)和式 ( 3 ) (3) (3)可得到实现Laplacian运算的几种模板如下所示:
H 1 = [ 0 − 1 0 − 1 4 − 1 0 − 1 0 ] H_1= \left[ \begin{matrix} 0 & -1 & 0 \\ -1 & 4 & -1\\ 0& -1& 0 \end{matrix} \right] H1=⎣⎡0−10−14−10−10⎦⎤
H 2 = [ − 1 − 1 − 1 − 1 8 − 1 − 1 − 1 − 1 ] H_2= \left[ \begin{matrix} -1 & -1 & -1 \\ -1 & 8 & -1\\ -1 & -1& -1 \end{matrix} \right] H2=⎣⎡−1−1−1−18−1−1−1−1⎦⎤
Laplacian运算由于只需要用一个模板,所以计算量比较小。Laplacian算子对图像中的噪声比较敏感,并且由于通常产生的是2个像素宽的边缘,所以很少直接用于边缘检测,通常是在已知边缘像素后用于确定该像素是在图像的暗区那边还是在明区那边,一般先对图像进行一次高斯模糊处理,然后在使用Laplacian算子来提取图像边缘(LOG算子,由Marr提出,因此也称为Marr边缘检测算法)。但由于拉普拉斯算子是二阶算子,所以利用其过零点的特性可精确定位边缘。Laplacian二阶边缘检测算子具有各向同性和旋转不变性,是一个标量算子。
在前面的内容中我们提到了Marr边缘检测算法,该算法克服了一般微分运算对于噪声敏感的缺点,利用能够反映人眼视觉特征的LOG算子对图像进行边缘检测,并结合二阶导数零交叉的性质对边缘进行定位。
典型的二维高斯函数的形式为:
G ( x , y , σ ) = − 1 2 π σ 2 e − x 2 + y 2 2 σ 2 G(x,y,\sigma)=-\frac{1}{2\pi\sigma^2} e^ {-{\frac {x^2+y^2}{2\sigma^2}}} G(x,y,σ)=−2πσ21e−2σ2x2+y2
其中 σ \sigma σ称为尺度因子,用于控制去噪效果,实验结果表明当 σ = 1 \sigma=1 σ=1时图像去噪效果最好。
由上面的内容也可以知道,Marr算法分为两个主要过程:
void Laplacian( InputArray src,
OutputArray dst,
int ddepth,
int ksize = 1,
double scale = 1,
double delta = 0,
int borderType = BORDER_DEFAULT );
其中ddepth一般设为-1表示输入输出图像类型一致。ksize必须为奇数,默认为1,表示是四领域算子,大于1则是八领域算子。
Mat blur_result, lap_result;
GaussianBlur(input, blur_result, Size(3, 3), 0);
Laplacian(blur_result, lap_result, CV_32F, 1, 1.0, 127.0, 4);
convertScaleAbs(lap_result, lap_result);
imshow("blur result", blur_result);
imshow("lap result", lap_result);