我使用的OpenCV 3.0。我做了一个汽车检测程序和我一直运行到重叠边界框的问题:
有没有一种方法合并下面的图片描述的重叠边界框?我用rectangle(frame, Point(x1, y1), Point(x2, y2), Scalar(255,255,255));
绘制的边界框。我搜索从similiar线程的答案,但我无法找到他们的帮助。我想,以形成合并这些边界框后一个外边框。
看来,如果你是显示你得到每个轮廓。你不必这样做。按照下面给出的算法和代码。
在这种情况下,你所能做的就是通过您检测并选择最大的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
}
}
问候
正如我在一个类似的帖子here已经提到,这是由非最大抑制最好解决的问题。
虽然你的代码是C ++,看看this pyimagesearch文章(蟒蛇),以获得关于如何工作的想法。
我翻译这个代码的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;
}