opencv-065-图像形态学(闭操作)

知识点

形态学的闭操作跟开操作一样也是基于腐蚀与膨胀两个操作的组合实现的
闭操作 = 膨胀 + 腐蚀
闭操作的作用:闭操作可以填充二值图像中孔洞区域,形成完整的闭合区域连通组件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
void cv::morphologyEx(
InputArray src,
OutputArray dst,
int op,
InputArray kernel,
Point anchor = Point(-1,-1),
int iterations = 1,
int borderType = BORDER_CONSTANT,
)
src 输入图像
dst 输出图像
op 形态学操作
kernel 结构元素
anchor 中心位置锚定
iterations 循环次数
borderType 边缘填充类型

其中op指定为MORPH_CLOSE 即表示使用闭操作

代码(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
#include <iostream>
#include <opencv2/opencv.hpp>

using namespace std;
using namespace cv;

/*
* 图像形态学(闭操作)
*/
int main() {
Mat src = imread("../images/cells.png");
if (src.empty()) {
cout << "could not load image.." << endl;
}
imshow("input", src);

// 二值图像
Mat gray, binary, result;
cvtColor(src, gray, COLOR_BGR2GRAY);
threshold(gray, binary, 0, 255, THRESH_BINARY | THRESH_OTSU);
imshow("binary", binary);

// 闭操作
Mat se1 = getStructuringElement(MORPH_RECT, Size(25, 5), Point(-1, -1));
Mat se2 = getStructuringElement(MORPH_RECT, Size(5, 25), Point(-1, -1));
morphologyEx(binary, result, MORPH_CLOSE, se1);
morphologyEx(result, result, MORPH_CLOSE, se2);
imshow("close_demo 25*5 5*25", result);

// 去除中间小方黑块
Mat se3 = getStructuringElement(MORPH_CROSS, Size(31, 21));
morphologyEx(result, result, MORPH_CLOSE, se3);
// imshow("cross", result);
morphologyEx(result, result, MORPH_CLOSE, se1);
morphologyEx(result, result, MORPH_CLOSE, se2);
imshow("final", result);

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
import cv2 as cv
import numpy as np

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

# 高斯模糊去噪声
gray = cv.cvtColor(src, cv.COLOR_BGR2GRAY)
ret, binary = cv.threshold(gray, 0, 255, cv.THRESH_BINARY | cv.THRESH_OTSU)
cv.imwrite("D:/binary1.png", binary)
cv.imshow("binary1", binary)

# 开操作
se1 = cv.getStructuringElement(cv.MORPH_RECT, (25, 5), (-1, -1))
se2 = cv.getStructuringElement(cv.MORPH_RECT, (5, 25), (-1, -1))
binary = cv.morphologyEx(binary, cv.MORPH_CLOSE, se1)
binary = cv.morphologyEx(binary, cv.MORPH_CLOSE, se2)

cv.imshow("binary", binary)
cv.imwrite("D:/binary2.png", binary)

cv.waitKey(0)
cv.destroyAllWindows()

结果

代码地址

github