OpenCV:合并重叠的矩形

时间:2015-04-08 19:02:37

标签: c++ opencv bounding-box object-detection

在使用OpenCV进行检测任务时,我一直遇到合并重叠边界框的问题;也就是说,基本上找到两个重叠边界框的并集​​周围的边界框。当由于某种原因,感兴趣的对象被分解成许多边界框而不是一个包罗万象的边框时,这在对象检测中出现了很多。

StackOverflow对算法解决方案和有用的外部库(例如thisthisthis)有几个答案,还有{{3}由OpenCV提供的功能(以及相关问题/错误:groupRectanglesthis等)。

我似乎发现上述解决方案对于我尝试执行的任务来说有点过于复杂。许多算法解决方案从数学角度解决了这个问题(更像是一个思想实验),而当像矩形的数量很高时,像rect1 | rect2这样的操作会变得很慢(它是O(N) ^ 2)处理所有事情)和groupRectangles有一些怪癖,使它只是部分有效。所以我想出了一个实际上非常有效的解决方案。我想我会在下面与其他需要快速解决这个常见问题的人分享。

随意评论和评论。

1 个答案:

答案 0 :(得分:2)

void mergeOverlappingBoxes(std::vector<cv::Rect> &inputBoxes, cv::Mat &image, std::vector<cv::Rect> &outputBoxes)
{
    cv::Mat mask = cv::Mat::zeros(image.size(), CV_8UC1); // Mask of original image
    cv::Size scaleFactor(10,10); // To expand rectangles, i.e. increase sensitivity to nearby rectangles. Doesn't have to be (10,10)--can be anything
    for (int i = 0; i < inputBoxes.size(); i++)
    {
        cv::Rect box = inputBoxes.at(i) + scaleFactor;
        cv::rectangle(mask, box, cv::Scalar(255), CV_FILLED); // Draw filled bounding boxes on mask
    }

    std::vector<std::vector<cv::Point>> contours;
    // Find contours in mask
    // If bounding boxes overlap, they will be joined by this function call
    cv::findContours(mask, contours, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_SIMPLE);
    for (int j = 0; j < contours.size(); j++)
    {
        outputBoxes.push_back(cv::boundingRect(contours.at(j)));
    }
}