【问题标题】:filtering unwanted contours - opencv with C++过滤不需要的轮廓 - 使用 C++ 的 opencv
【发布时间】:2017-04-27 08:51:43
【问题描述】:

我正在处理一个视频,我想检测一些对象。

首先,我删除背景,然后将其设为灰色并使用cv::threshold 制作二值图像,然后使用cv::findcontours

我想删除太长和太短的轮廓。 为此,我在“Opencv 2 cookbook”中找到了一个代码。但它在我的视频的第 21 帧出现运行时错误。

// Eliminate too short or too long contours
    size_t cmin{ 15 }; // minimum contour length
    size_t cmax{ 120 }; // maximum contour length


    std::vector<std::vector<cv::Point> >::
        const_iterator itc = contours.begin();
    while (itc != contours.end()) {
        if (itc->size() < cmin || itc->size() > cmax)
            itc = contours.erase(itc);
        else
            ++itc;
    }

我搜索并找到了另一个代码,它在同一帧上出现了相同的错误:

double min_area = 500; // area threshold
    double max_area = 1500; // area threshold
    for (int i = 0; i < contours.size(); i++) // iterate through each contour.
    {
        double area = contourArea(contours[i], false);  //  Find the area of contour
        if (area < min_area || area > max_area)
            contours.erase(contours.begin() + i);
    }

我写了一个代码来创建一个新的向量,并在其中复制接受的轮廓。但它在同一帧上也有同样的错误:

std::vector<std::vector<cv::Point> > goodcontours;
    size_t cmin{ 15 };
    size_t cmax{ 120 };
    double contourlength = 1;
    size_t contoursize = contours.size();
    for (int i = 0; i != contoursize;i++) {
        contourlength = cv::arcLength(contours[i], true);
        if (contourlength > cmin && contourlength < cmax)
            goodcontours.push_back(contours.at(i));
    }

我尝试了其他视频,但所有视频在特定帧上都有相同的问题。

在出现错误之前,我仍然可以看到不需要的轮廓,这意味着它们并没有真正消除。

错误只是说:

0x75017FB2 (ucrtbase.dll) 处未处理的异常

你对过滤轮廓有什么建议吗?

one of my video frames contours

【问题讨论】:

  • 猜测这与不符合contourArea 假设的轮廓有关(也许太小了?)。必须有一些更详细的信息消息 - 仔细查看

标签: c++ opencv contour


【解决方案1】:

这是我找到的答案:

cv::findContours(image,contours,CV_RETR_LIST,mode,cv::Point(offset_x,offset_y));
    
    for(int i=0;i<contours.size();i++)
    {
      AreaContour=cv::contourArea(contours[i]);
      if(AreaContour<MaxAreaContour && AreaContour>MinAreaContour)
        drawContours(Result,contours,i,cv::Scalar(DrawColor),Thickness,LineType,cv::noArray(),2147483647,cv::Point(DrawOffset_x,DrawOffset_y));
    
    }

【讨论】:

    【解决方案2】:

    这是我的 Find_Filter_Draw Contours 函数,分享它可能对某人有帮助

    bool Find_Filter_Draw_Contours(){
       // Find Contours on our working image which is ... currentImage.
        cv::Mat hierarchy = cv::Mat();
        std::vector<std::vector<cv::Point> > contours;
        cv::Mat contourOutput = currentImage.clone();
    
        cv::findContours(contourOutput, contours, hierarchy, cv::RETR_CCOMP, cv::CHAIN_APPROX_NONE);
        hierarchy.release();
    
        // filter them based on Area.  good to remove small dots
        double minArea = 50; 
        double maxArea = 900000;
    
       std::vector<std::vector<cv::Point> > GoodContours;
    
      for (size_t idx = 0; idx < contours.size(); idx++) {
            double area = cv::contourArea(contours[idx]);
           // http://www.cplusplus.com/reference/limits/numeric_limits/
            if (area >= (minArea == -1 ? std::numeric_limits<double>::min() : minArea) && area <= (maxArea == -1 ? std::numeric_limits<double>::max() : maxArea)) {
                  GoodContours.push_back(contours.at(idx));
            }
        }
    
        //Draw the contours
        cv::Mat contourImage(currentImage.size(), CV_8UC3, cv::Scalar(0,0,0));
        cv::Scalar colors[3];
        colors[0] = cv::Scalar(255, 0, 0);
        colors[1] = cv::Scalar(0, 255, 0);
        colors[2] = cv::Scalar(0, 0, 255);
    
    
          for (size_t idx = 0; idx < GoodContours.size(); idx++) {
              cv::drawContours(contourImage, GoodContours, idx, colors[idx % 3]);
          }
    
          cv::imshow("Input Image", currentImage);
          cv::imshow("Contours", contourImage);
    
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-05-06
      • 2020-09-22
      • 2014-07-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-12-13
      相关资源
      最近更新 更多