opencv-033-图像梯度之拉普拉斯算子(二阶导数算子)

知识点

图像的一阶导数算子可以得到图像梯度局部梯度相应值,二阶导数可以通过快速的图像像素值强度的变化来检测图像边缘,其检测图像边缘的原理跟图像的一阶导数有点类似,只是在二阶导数是求X、Y方向的二阶偏导数,对图像来说:

  • X方向的二阶偏导数就是 dx = f(x+1, y) + f(x-1, y) – 2*f(x, y)

  • Y方向的二阶偏导数就是 dy = f(x, y+1) + f(x, y-1) – 2*f(x, y)

对X方向与Y方向进行叠加最终就得到delta对应的二阶导数算子。

API

1
2
3
4
5
6
7
8
9
10
11
12
13
// OpenCV中Laplacian滤波函数就是二阶导数发现边缘的函数
void cv::Laplacian(
InputArray src,
OutputArray dst,
int ddepth, // 深度默认是-1表示输入与输出图像相同
int ksize = 1,// 必须是奇数, 等于1是四邻域算子,大于1改用八邻域算子
double scale = 1,
double delta = 0, // 对输出图像加上常量值
int borderType = BORDER_DEFAULT
)

Python:
dst = cv.Laplacian(src, ddepth[, dst[, ksize[, scale[, delta[, borderType]]]] )

代码(c++,python)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#include <iostream>
#include <opencv2/opencv.hpp>

using namespace std;
using namespace cv;

/*
* 拉普拉斯算子(二阶导数算子)
*/
int main() {
Mat src = imread("../images/test.png");
if (src.empty()) {
cout << "could not load image.." << endl;
}
imshow("input", src);

Mat blured, dst;
GaussianBlur(src, blured, Size(3,3), 0);
Laplacian(blured, dst, CV_32F, 1, 1.0, 127.0);
convertScaleAbs(dst, dst);
imshow("Laplacian", dst);

waitKey(0);
return 0;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
import cv2 as cv
import numpy as np

image = cv.imread("D:/images/yuan_test.png")
cv.namedWindow("input", cv.WINDOW_AUTOSIZE)
cv.imshow("input", image)

h, w = image.shape[:2]
src = cv.GaussianBlur(image, (0, 0), 1)
dst = cv.Laplacian(src, cv.CV_32F, ksize=3, delta=127)
dst = cv.convertScaleAbs(dst)
result = np.zeros([h, w*2, 3], dtype=image.dtype)
result[0:h,0:w,:] = image
result[0:h,w:2*w,:] = dst
cv.imshow("result", result)
cv.imwrite("D:/laplacian_08.png", result)


cv.waitKey(0)
cv.destroyAllWindows()

结果

代码地址

github