簡體   English   中英

在OpenCV中合並重疊矩形

[英]Merging Overlapping Rectangle in OpenCV

我正在使用OpenCV 3.0。 我做了一個汽車檢測程序,我一直遇到重疊邊界框的問題:

在此輸入圖像描述

是否有一種方法可以合並重疊的邊框,如下圖所示? 我用過rectangle(frame, Point(x1, y1), Point(x2, y2), Scalar(255,255,255)); 畫那些邊界框。 我已經從類似的線程中尋找答案,但找不到它們有幫助。 我想在合並這些邊界框后形成一​​個外部邊界矩形。

問題

似乎您正在顯示您正在獲得的每個輪廓。 你不必那樣做。 請遵循下面給出的算法和代碼。

算法

在這種情況下,您可以做的是遍歷您檢測到的每個輪廓並選擇最大的boundingRect 您不必顯示檢測到的每個輪廓。

這是您可以使用的代碼。

for( int i = 0; i< contours.size(); i++ ) // iterate through each contour. 
      {
       double a=contourArea( contours[i],false);  //  Find the area of contour
       if(a>largest_area){
       largest_area=a;
       largest_contour_index=i;                //Store the index of largest contour
       bounding_rect=boundingRect(contours[i]); // Find the bounding rectangle for biggest contour
       }

      }

問候

正如我在此處的類似文章中所提到的,這是通過非最大抑制來最好地解決的問題。

盡管您的代碼是C ++,但請查看此pyimagesearch文章(python),以了解其工作原理。

我已經將此代碼從python轉換為C ++。

struct detection_box
{
    cv::Rect box;               /*!< Bounding box */
    double svm_val;             /*!< SVM response at that detection*/
    cv::Size res_of_detection;  /*!< Image resolution at which the detection occurred */
};

/*!
\brief Applies the Non Maximum Suppression algorithm on the detections to find the detections that do not overlap

The svm response is used to sort the detections. Translated from http://www.pyimagesearch.com/2014/11/17/non-maximum-suppression-object-detection-python/

\param boxes list of detections that are the input for the NMS algorithm
\param overlap_threshold the area threshold for the overlap between detections boxes. boxes that have overlapping area above threshold are discarded


\returns list of final detections that are no longer overlapping
*/
std::vector<detection_box> nonMaximumSuppression(std::vector<detection_box> boxes, float overlap_threshold)
{
    std::vector<detection_box> res;
    std::vector<float> areas;

    //if there are no boxes, return empty 
    if (boxes.size() == 0)
        return res;

    for (int i = 0; i < boxes.size(); i++)
        areas.push_back(boxes[i].box.area());

    std::vector<int> idxs = argsort(boxes);     

    std::vector<int> pick;          //indices of final detection boxes

    while (idxs.size() > 0)         //while indices still left to analyze
    {
        int last = idxs.size() - 1; //last element in the list. that is, detection with highest SVM response
        int i = idxs[last];
        pick.push_back(i);          //add highest SVM response to the list of final detections

        std::vector<int> suppress;
        suppress.push_back(last);

        for (int pos = 0; pos < last; pos++)        //for every other element in the list
        {
            int j = idxs[pos];

            //find overlapping area between boxes
            int xx1 = max(boxes[i].box.x, boxes[j].box.x);          //get max top-left corners
            int yy1 = max(boxes[i].box.y, boxes[j].box.y);          //get max top-left corners
            int xx2 = min(boxes[i].box.br().x, boxes[j].box.br().x);    //get min bottom-right corners
            int yy2 = min(boxes[i].box.br().y, boxes[j].box.br().y);    //get min bottom-right corners

            int w = max(0, xx2 - xx1 + 1);      //width
            int h = max(0, yy2 - yy1 + 1);      //height

            float overlap = float(w * h) / areas[j];    

            if (overlap > overlap_threshold)        //if the boxes overlap too much, add it to the discard pile
                suppress.push_back(pos);
        }

        for (int p = 0; p < suppress.size(); p++)   //for graceful deletion
        {
            idxs[suppress[p]] = -1;
        }

        for (int p = 0; p < idxs.size();)
        {
            if (idxs[p] == -1)
                idxs.erase(idxs.begin() + p);
            else
                p++;
        }

    }

    for (int i = 0; i < pick.size(); i++)       //extract final detections frm input array
        res.push_back(boxes[pick[i]]);

    return res;

}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM