zoukankan      html  css  js  c++  java
  • OpenCV学习(6)--更多形态转化、Hit-or-Miss变换、Hit-or-Miss变换、图像金字塔

    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:
     0: Opening - 1: Closing 
     2: Gradient - 3: Top Hat 
     4: Black Hat", "Morphology Transformations Demo", &morphOperator, maxOperator, MorphologyOperations);
    28         cv::createTrackbar("Element:
     0: Rect - 1: Cross - 2: Ellipse", "Morphology Transformations Demo", &morphElem, maxElem, MorphologyOperations);
    29         cv::createTrackbar("Kernel size:
     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 }
  • 相关阅读:
    关于如何实现NSNotificationCenter在不同的VC对象之间发送通知
    关于iOS如何实现一个单例
    C++中级-类模板
    C++中级-文件读写
    C++中级-多态
    C++中级-继承
    C++中级-friend关键字访问类中private
    C++中级-(静态成员和对象丶this指针丶常函数和对象、成员函数和对象)
    C++中级-(构造函数,拷贝构造函数,析构函数)
    C++中级-类的封装
  • 原文地址:https://www.cnblogs.com/lnlin/p/13777804.html
Copyright © 2011-2022 走看看