Advertisement

【Opencv4快速入门】轮廓检测findContours

阅读量:

7.2 轮廓检测findContours

  • 7.2.1 轮廓查找findContours
  • 7.2.2 轮廓绘制drawContours

图像轮廓是指图像中对象的边界,是图像目标的外部特征,这个特征对于图像分析、目标识别和理解更深层次的含义具有重要的作用。

7.2.1 轮廓查找findContours

图像的轮廓补单能够提供物体的边缘,而且能提供物体边缘之间的层次关系及拓扑关系。我们可以将图像轮廓发现简单理解为带有结构关系的边缘检测。例如如下图像,含有五个边缘:
在这里插入图片描述
我们为这五个边缘编号,分别为0,1,2,3,4,如下:
在这里插入图片描述
图中5个不联通的图像边缘,分别是0,1,2,3,4。其中0号轮廓的层级最高,其次是1,3,4号,是并列的层级。最后由于2号被1号包围,所以2号的层级最低。不同轮廓之间的层级关系可以用如下图来描述:
在这里插入图片描述
为了更好的表明轮廓之间的层级关系,通常使用四个参数cv::Vec4i来描述,这四个参数的含义依次为:

  • 同层下一个子轮廓的索引(无下一个子轮廓则索引为-1)
  • 同层上一个子轮廓的索引(无上一个子轮廓则索引为-1)
  • 下一层顶一个子轮廓的索引(无则索引为-1)
  • 上层父轮廓的索引(无父轮廓则索引为-1)

有了上述定义后,图中5个轮廓的关系便清楚了,

轮廓0:[-1, -1, 1, -1]

轮廓1:[3, -1, 2, 0]

轮廓2:[-1, -1, -1, 1]

轮廓3:[4, 1, -1, 0]

轮廓4:[-1, 3, -1, 0]

Opencv中的void findContours函数用于从二值化图像中寻找轮廓,并返回轮廓的层级关系。由于输入是二值化图像,所以图像要提前经过灰度化、滤波、二值化等操作生成二值化图像。

7.2.2 轮廓绘制drawContours

复制代码
    #include <iostream>
    #include <opencv2/opencv.hpp>
    
    int main(int argc, char const *argv[]) {
    
      cv::Mat img = cv::imread("image/README/1698488030768.png");
      if (img.empty()) {
    std::cout << "Please check the input image!" << std::endl;
    return 0;
      }
      cv::imshow("src", img);
      cv::Mat gray, binary;
      cv::cvtColor(img, gray, cv::COLOR_BGR2GRAY);
      cv::GaussianBlur(gray, gray, cv::Size(3, 3), 4, 4);
      cv::threshold(gray, binary, 170, 255, cv::THRESH_BINARY | cv::THRESH_OTSU);
      // find and draw
      std::vector<std::vector<cv::Point>> contours; // contours
      std::vector<cv::Vec4i> hierarchy;             // save the contours
      cv::findContours(binary, contours, hierarchy, cv::RETR_TREE,
                   cv::CHAIN_APPROX_SIMPLE, cv::Point());
      // blue green red yellow pink
      cv::Scalar color_set[5] = {cv::Scalar(255, 0, 0), cv::Scalar(0, 255, 0),
                             cv::Scalar(0, 0, 255), cv::Scalar(0, 255, 255),
                             cv::Scalar(255, 0, 255)};
      // draw
      for (int i = 0; i < contours.size(); i++) {
    cv::drawContours(img, contours, i, color_set[i % 5], 2);
      }
      // print
      for (int i = 0; i < hierarchy.size(); i++) {
    std::cout << hierarchy[i] << std::endl;
      }
      cv::imshow("results", img);
      cv::waitKey(0);
      cv::destroyAllWindows();
    
      return 0;
    }
    
    
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
    

最终效果如下:
在这里插入图片描述

全部评论 (0)

还没有任何评论哟~