一杯清酒邀明月
天下本无事,庸人扰之而烦耳。

Laplace算子和Sobel算子一样,属于空间锐化滤波操作。起本质与前面的Spatial Filter操作大同小异,下面就通过Laplace算子来介绍一下空间锐化滤波,并对OpenCV中提供的Laplacian函数进行一些说明。

数学原理

离散函数导数

离散函数的导数退化成了差分,一维一阶差分公式和二阶差分公式分别为,

CodeCogsEqn

CodeCogsEqn(2)

Laplace算子的差分形式

分别对Laplace算子x,y两个方向的二阶导数进行差分就得到了离散函数的Laplace算子。

在一个二维函数f(x,y)中,x,y两个方向的二阶差分分别为,

CodeCogsEqn(3)

CodeCogsEqn(4)

 

所以Laplace算子的差分形式为,

CodeCogsEqn(5)

写成filter mask的形式如下,

0 1 0
1 -4 1
0 1 0
注意该mask的特点,mask在上下左右四个90度的方向上结果相同,也就是说在90度方向上无方向性。为了让该mask在45度的方向上也具有该性质,对该filter mask进行扩展定义为,
1 1 1
1 -8 1
1 1 1
 

有时我们也会见到不同于上述结果的Laplace算子的filter mask,

0 -1 0
-1 4 -1
0 -1 0
 
-1 -1 -1
-1 8 -1
-1 -1 -1

其原因是在定义二阶导数的时候采用了相反的定义,这个无关紧要,但是要注意,当用Laplace算子滤波后的图像与原图叠加时,混合操作是加还是减因上述的定义而异。

图像的Laplace操作

如同本文开始时说的那样,将Laplace算子写成filter mask后,其操作大同小异于其他的空间滤波操作。将filter mask在原图上逐行移动,然后mask中数值与其重合的像素相乘后求和,赋给与mask中心重合的像素,对图像的第一,和最后的行和列无法做上述操作的像素赋值零,就得到了拉普拉斯操作结果。

拉普拉斯操作结果与原图的混合

因为Laplace算子是二阶导数操作,其在强调图像素中灰度不连续的部分的同时也不在强调灰度值连续的部分。这样会产生一个具有很明显的灰度边界,但是没有足够特征的黑色背景。背景特征可以通过原图像与Laplace算子操作后的图像混合恢复。用公式,

CodeCogsEqn(6)

其中的参数c的取值和上面的两种mask定义有关,当mask中心的数值取正时c=-1,相反c=1;


Laplacian( src_gray, dst, ddepth, kernel_size, scale, delta, BORDER_DEFAULT );

src_gray: 输入图像。
dst: 输出图像
ddepth: 输出图像的深度。 因为输入图像的深度是 CV_8U ,这里我们必须定义 ddepth = CV_16S 以避免外溢。
kernel_size: 内部调用的 Sobel算子的内核大小,此例中设置为3。
scale, delta 和 BORDER_DEFAULT: 使用默认值。
最后应将输出图像的深度转化为 CV_8U : convertScaleAbs( dst, abs_dst );


高斯模糊-灰度-拉普拉斯计算-绝对值(convertScaleAbs)-显示结果

 1 #include <opencv2/opencv.hpp>  
 2 #include <stdio.h>  
 3 #include <stdlib.h>  
 4  
 5 using namespace cv;  
 6 using namespace std;  
 7  
 8 char file[] = "1.jpg";
 9 int main(int argc, char** argv)  
10 {  
11     Mat img = imread(file, -1);
12     pyrDown(img, img, Size(img.cols/2, img.rows/2));
13     imshow("1",img);
14  
15     Mat gray, laplaci, final;
16  
17     //高斯模糊
18     GaussianBlur(img, img, Size(5,5), 0, 0);
19  
20     //转灰度图像
21     cvtColor(img, gray, CV_BGR2GRAY);
22     imshow("gray", gray);imwrite("gray.jpg", gray);
23  
24     //拉普拉斯处理
25     Laplacian(gray, laplaci, CV_16S, 3, 1, 0);
26  
27     //绝对值处理
28     convertScaleAbs(laplaci, laplaci);
29  
30     //展示图像
31     imshow("laplaci", laplaci);imwrite("laplaci.jpg", laplaci);
32  
33     //后期处理
34     Mat kernel = getStructuringElement(MORPH_RECT, Size(3,3), Point(-1,-1));
35     morphologyEx(laplaci, final, CV_MOP_TOPHAT, kernel);
36     threshold(final, final,100, 255, THRESH_TOZERO_INV);
37     threshold(final, final,20, 90, THRESH_BINARY);
38     imshow("final", final);imwrite("final.jpg", final);
39         
40     waitKey();
41     return 1;
42 } 

原图

gray

拉普拉斯

final

posted on 2020-05-03 10:35  一杯清酒邀明月  阅读(3407)  评论(0编辑  收藏  举报