OpenCV更多形态转化:开盘、闭幕、形态梯度、顶帽、黑帽

1 static class MorphologyOperationsExample {
2 // OpenCV更多的形态转化
3 /*
4 开盘:
5 先侵蚀 后扩张 dst = open(src, element) = dilate(erode(src, element))
6 去除亮色小物体
7 闭幕:
8 先扩张 后侵蚀 dst = close(src, element) = erode(dilate(src, element))
9 去除暗区小孔
10 形态梯度:
11 dst = morph_grad(src, element) = dilate(src, element) - erode(src, element)
12 找到对象轮廓
13 顶帽:
14 dst = tophat(src, element) = src - open(src, element)
15 黑帽:
16 dst = blackhat(src, element) = close(src, element) - src
17 */
18
19 public:
20 static int showExample(string imageName) {
21 src = cv::imread(imageName, cv::IMREAD_COLOR);
22
23 if (src.empty())
24 return -1;
25
26 cv::namedWindow("Morphology Transformations Demo", cv::WINDOW_AUTOSIZE);
27 cv::createTrackbar("Operator:\n 0: Opening - 1: Closing \n 2: Gradient - 3: Top Hat \n 4: Black Hat", "Morphology Transformations Demo", &morphOperator, maxOperator, MorphologyOperations);
28 cv::createTrackbar("Element:\n 0: Rect - 1: Cross - 2: Ellipse", "Morphology Transformations Demo", &morphElem, maxElem, MorphologyOperations);
29 cv::createTrackbar("Kernel size:\n 2n + 1", "Morphology Transformations Demo", &morphSize, maxKernelSize, MorphologyOperations);
30 MorphologyOperations(0, 0);
31 cv::waitKey(0);
32 return 0;
33 }
34
35 static void MorphologyOperations(int, void*) {
36 // Since MORPH_X : 2 3 4 5 6
37 int operation = morphOperator + 2;
38 cv::Mat element = cv::getStructuringElement(morphElem, cv::Size(2 * morphSize + 1, 2 * morphSize + 1), cv::Point(morphSize, morphSize));
39 // cv::morphologyEx() 通过operation控制做什么操作
40 // https://docs.opencv.org/4.2.0/d4/d86/group__imgproc__filter.html#gga7be549266bad7b2e6a04db49827f9f32a08d3cc3a2ace00cec488966d31fa29ea
41 cv::morphologyEx(src, dst, operation, element);
42 /*
43 enum cv::MorphShapes {
44 cv::MORPH_RECT = 0,
45 cv::MORPH_CROSS = 1,
46 cv::MORPH_ELLIPSE = 2
47 }
48
49 enum cv::MorphTypes {
50 cv::MORPH_ERODE = 0,
51 cv::MORPH_DILATE = 1,
52 cv::MORPH_OPEN = 2,
53 cv::MORPH_CLOSE = 3,
54 cv::MORPH_GRADIENT = 4,
55 cv::MORPH_TOPHAT = 5,
56 cv::MORPH_BLACKHAT = 6,
57 cv::MORPH_HITMISS = 7
58 }
59 */
60 cv::imshow("Morphology Transformations Demo", dst);
61 }
62
63 // 需要在类外初始化
64 static cv::Mat src;
65 static cv::Mat dst;
66 static int morphElem; // = 0
67 static int morphSize; // = 0
68 static int morphOperator; // = 0
69 static int const maxOperator = 4;
70 static int const maxElem = 2;
71 static int const maxKernelSize = 21;
72 };
73
74 int MorphologyOperationsExample::morphElem = 0;
75 int MorphologyOperationsExample::morphSize = 0;
76 int MorphologyOperationsExample::morphOperator = 0;
77 cv::Mat MorphologyOperationsExample::src;
78 cv::Mat MorphologyOperationsExample::dst;
79
80 int useThisMorphologyOperationsExample(void) {
81 MorphologyOperationsExample::showExample("blackWord.png");
82
83 cv::waitKey(0);
84 return 0;
85

Hit-or-Miss变换:

1 int exampleHist_or_Miss(void) {
2 // Hit-or-Miss变换
3 // 创建输入图片
4 cv::Mat inputImage = (cv::Mat_<uchar>(8, 8) <<
5 0, 0, 0, 0, 0, 0, 0, 0,
6 0, 255, 255, 255, 0, 0, 0, 255,
7 0, 255, 255, 255, 0, 0, 0, 0,
8 0, 255, 255, 255, 0, 255, 0, 0,
9 0, 0, 255, 0, 0, 0, 0, 0,
10 0, 0, 255, 0, 0, 255, 255, 0,
11 0, 255, 0, 255, 0, 0, 255, 0,
12 0, 255, 255, 255, 0, 0, 0, 0);
13
14 cv::Mat kernel = (cv::Mat_<int>(3, 3) <<
15 0, 1, 0,
16 1, -1, 1,
17 0, 1, 0);
18
19 cv::Mat outputImage;
20 cv::morphologyEx(inputImage, outputImage, cv::MORPH_HITMISS, kernel);
21 const int rate = 10;
22 kernel = (kernel + 1) * 127;
23 kernel.convertTo(kernel, CV_8U);
24 cv::resize(kernel, kernel, cv::Size(), rate, rate, cv::INTER_NEAREST);
25 cv::imshow("kernel", kernel);
26 cv::resize(inputImage, inputImage, cv::Size(), rate, rate, cv::INTER_NEAREST);
27 cv::imshow("Original", inputImage);
28 cv::resize(outputImage, outputImage, cv::Size(), rate, rate, cv::INTER_NEAREST);
29 cv::imshow("Hit or Miss", outputImage);
30
31 cv::waitKey(0);
32 return 0;
33

提取水平线和垂直线:

1 int getHVExample(void) {
2 // 使用形态学操作来提取水平和垂直线
3 cv::Mat src = cv::imread("melody.png", cv::IMREAD_COLOR);
4
5 if (src.empty()) {
6 std::cout << "Read Failed!" << std::endl;
7 return -1;
8 }
9
10 cv::imshow("Src", src);
11 cv::Mat gray;
12
13 if (src.channels() == 3) {
14 cv::cvtColor(src, gray, cv::COLOR_BGR2GRAY);
15 }
16 else {
17 gray = src;
18 }
19
20 cv::imshow("Gray", gray);
21 cv::Mat bw;
22 // 自适应阈值化函数adaptiveThreshold来实现自适应阈值处理
24 cv::adaptiveThreshold(~gray, bw, 255, cv::ADAPTIVE_THRESH_MEAN_C, cv::THRESH_BINARY, 15, -2);
25 cv::imshow("Binary", bw);
26
27 cv::Mat horizontal = bw.clone();
28 cv::Mat vertical = bw.clone();
29
30 int horizontalsize = horizontal.cols / 30;
31 cv::Mat horizontalStructure = cv::getStructuringElement(cv::MORPH_RECT, cv::Size(horizontalsize, 1));
32 cv::erode(horizontal, horizontal, horizontalStructure, cv::Point(-1, -1));
33 cv::dilate(horizontal, horizontal, horizontalStructure, cv::Point(-1, -1));
34 cv::imshow("Horizontal", horizontal);
35
36 int verticalsize = vertical.rows / 30;
37 cv::Mat verticalStructure = cv::getStructuringElement(cv::MORPH_RECT, cv::Size(1, verticalsize));
38 cv::erode(vertical, vertical, verticalStructure, cv::Point(-1, -1));
39 cv::dilate(vertical, vertical, verticalStructure, cv::Point(-1, -1));
40 cv::imshow("Vertical", vertical);
41
42 // 对二进制图像进行非操作
44 cv::bitwise_not(vertical, vertical);
45 cv::imshow("vertical_bit", vertical);
46
47 // 扩张边界 平滑图像
48 // 1 extract edges
49 cv::Mat edges;
50 cv::adaptiveThreshold(vertical, edges, 255, cv::ADAPTIVE_THRESH_MEAN_C, cv::THRESH_BINARY, 3, -2);
51 cv::imshow("Edges", edges);
52 // 2 dilate edges
53 cv::Mat kernel = cv::Mat::ones(2, 2, CV_8UC1);
54 cv::dilate(edges, edges, kernel);
55 cv::imshow("dilate", edges);
56 // 3 src.copyTo(smooth)
57 cv::Mat smooth;
58 vertical.copyTo(smooth);
59 // 4 blur smooth img
60 // blur()函数可以用标准化的盒式过滤器来平滑图像。
62 cv::blur(smooth, smooth, cv::Size(2, 2));
63 // 5 smooth.copyTo(src, edges)
64 smooth.copyTo(vertical, edges);
65 cv::imshow("smooth", vertical);
66
67
68 cv::waitKey(0);
69 return 0;
70

图像金字塔变换(扩大/缩小):

1 int showPyramidsDemo(void) {
2 // 图像金字塔
3 // 将图像转化为与原始图像不同的大小 放大/缩小
4 // 高斯金字塔:较常用,用于缩减图像
5 // 拉普拉斯金字塔:从金字塔中较低的图像重建上采样图像(分辨率较低)
6 cv::Mat src;
7 cv::Mat dst;
8 cv::Mat tmp;
9
10 src = cv::imread("small.jpg", cv::IMREAD_COLOR);
11 if (src.empty()) {
12 std::cout << "Failed read!" << std::endl;
13 return -1;
14 }
15
16 tmp = src;
17 dst = tmp;
18 cv::imshow("Pyramids Demo", src);
19
20 cv::pyrUp(src, dst, cv::Size(src.cols * 2, src.rows * 2));
21 cv::imshow("Up Demo", dst);
22 //tmp = dst;
23
24 cv::pyrDown(src, tmp, cv::Size(src.cols / 2, src.rows / 2));
25 cv::imshow("Down Demo", tmp);
26 //tmp = dst;
27 /*
28 while (true) {
29 char c = cv::waitKey(0);
30
31 if (c == 27)
32 break;
33 if (c == 'u') {
34 cv::pyrUp(tmp, dst, cv::Size(tmp.cols * 2, tmp.rows * 2));
35 std::cout << "Zoom In: Image * 2" << std::endl;
36 }
37 if (c == 'd') {
38 cv::pyrDown(tmp, dst, cv::Size(tmp.cols / 2, tmp.rows / 2));
39 std::cout << "Zoom Out: Image / 2" << std::endl;
40 }
41
42 cv::imshow("Pyramids Demo", dst);
43 tmp = dst;
44 }
45 */
46 cv::waitKey(0);
47 return 0;
48

 

转载请注明出处