首页 > 其他 > 详细

OpenCV学习(6)--更多形态转化、Hit-or-Miss变换、Hit-or-Miss变换、图像金字塔

时间:2020-10-07 21:44:14      阅读:61      评论:0      收藏:0      [点我收藏+]

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来实现自适应阈值处理
23     // https://blog.csdn.net/wenhao_ir/article/details/51565517
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     // 对二进制图像进行非操作
43     // https://blog.csdn.net/u011028345/article/details/77278467
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()函数可以用标准化的盒式过滤器来平滑图像。
61     // https://blog.csdn.net/duwangthefirst/article/details/79971322
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 }

 

OpenCV学习(6)--更多形态转化、Hit-or-Miss变换、Hit-or-Miss变换、图像金字塔

原文:https://www.cnblogs.com/lnlin/p/13777804.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!