opencv-032-图像梯度之robert算子与prewitt算子

知识点

图像的一阶导数算子除了sobel算子之外,常见的还有robert算子与prewitt算子,它们也都是非常好的可以检测图像的梯度边缘信息,通过OpenCV中自定义滤波器,使用自定义创建的robert与prewitt算子就可以实现图像的rober与prewitt梯度边缘检测。

API

1
2
3
4
5
6
7
8
9
10
11
12
filter2D(
InputArray src,
OutputArray dst,
int ddepth,
InputArray kernel,
Point anchor = Point(-1,-1),
double delta = 0,
int borderType = BORDER_DEFAULT
)

Python:
dst =cv.filter2D(src, ddepth, kernel[, dst[, anchor[, 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
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
#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);

// Robert算子
Mat robert_x = (Mat_<int>(2, 2) << 1, 0, 0, -1);
Mat robert_y = (Mat_<int>(2, 2) << 0, -1, 1, 0);
Mat robert_grad_x, robert_grad_y, robert_grad;
filter2D(src, robert_grad_x, CV_16S, robert_x);
filter2D(src, robert_grad_y, CV_16S, robert_y);
convertScaleAbs(robert_grad_x, robert_grad_x);
convertScaleAbs(robert_grad_y, robert_grad_y);
add(robert_grad_x, robert_grad_y, robert_grad);
convertScaleAbs(robert_grad, robert_grad);
imshow("robert_grad_x", robert_grad_x);
imshow("robert_grad_y", robert_grad_y);
imshow("robert_grad", robert_grad);

// 定义Prewitt算子
Mat prewitt_x = (Mat_<char>(3, 3) << -1, 0, 1,
-1, 0, 1,
-1, 0, 1);
Mat prewitt_y = (Mat_<char>(3, 3) << -1, -1, -1,
0, 0, 0,
1, 1, 1);
Mat prewitt_grad_x, prewitt_grad_y, prewitt_grad;
filter2D(src, prewitt_grad_x, CV_32F, prewitt_x);
filter2D(src, prewitt_grad_y, CV_32F, prewitt_y);
convertScaleAbs(prewitt_grad_x, prewitt_grad_x);
convertScaleAbs(prewitt_grad_y, prewitt_grad_y);
add(prewitt_grad_x, prewitt_grad_y, prewitt_grad);
convertScaleAbs(prewitt_grad, prewitt_grad);
imshow("prewitt_grad_x", prewitt_grad_x);
imshow("prewitt_grad_y", prewitt_grad_y);
imshow("prewitt_grad", prewitt_grad);

waitKey(0);
return 0;
}
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
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
import cv2 as cv
import numpy as np

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

robert_x = np.array([[1, 0],[0, -1]], dtype=np.float32)
robert_y = np.array([[0, -1],[1, 0]], dtype=np.float32)

prewitt_x = np.array([[-1, 0, 1], [-1, 0, 1], [-1, 0, 1]], dtype=np.float32)
prewitt_y = np.array([[-1, -1, -1], [0, 0, 0], [1, 1, 1]], dtype=np.float32)

robert_grad_x = cv.filter2D(src, cv.CV_16S, robert_x)
robert_grad_y = cv.filter2D(src, cv.CV_16S, robert_y)
robert_grad_x = cv.convertScaleAbs(robert_grad_x)
robert_grad_y = cv.convertScaleAbs(robert_grad_y)

prewitt_grad_x = cv.filter2D(src, cv.CV_32F, prewitt_x)
prewitt_grad_y = cv.filter2D(src, cv.CV_32F, prewitt_y)
prewitt_grad_x = cv.convertScaleAbs(prewitt_grad_x)
prewitt_grad_y = cv.convertScaleAbs(prewitt_grad_y)

# cv.imshow("robert x", robert_grad_x);
# cv.imshow("robert y", robert_grad_y);
# cv.imshow("prewitt x", prewitt_grad_x);
# cv.imshow("prewitt y", prewitt_grad_y);

h, w = src.shape[:2]
robert_result = np.zeros([h, w*2, 3], dtype=src.dtype)
robert_result[0:h,0:w,:] = robert_grad_x
robert_result[0:h,w:2*w,:] = robert_grad_y
cv.imshow("robert_result", robert_result)

prewitt_result = np.zeros([h, w*2, 3], dtype=src.dtype)
prewitt_result[0:h,0:w,:] = prewitt_grad_x
prewitt_result[0:h,w:2*w,:] = prewitt_grad_y
cv.imshow("prewitt_result", prewitt_result)

cv.imwrite("D:/prewitt.png", prewitt_result)
cv.imwrite("D:/robert.png", robert_result)

cv.waitKey(0)
cv.destroyAllWindows()

结果

代码地址

github