OpenCV的;对vector <rect>进行排序并删除某些条目</rect>

时间:2014-01-09 06:53:53

标签: c++ sorting opencv vector

我有这个问题我无法绕过头脑。我试图检测并跟踪视频中的某些内容。因此我使用GaussianBlur(), threshold(), findContours(),等函数。

findContours()给我一个轮廓矢量,后来转换成边界矩形。到现在为止还挺好。

我现在需要从带有边界矩形的向量中得到的是它们按大小(area)排序,并且只包含未被另一个矩形包围的矩形。

我试图绘制一个小草图以便更好地理解,click here for image

所以我要找的是#8是第一个条目,后跟#1, #3,.... 应删除#2,#4, #9, #10 and #11等条目。

据我所知,矢量不适合排序和删除。所以我试着将矢量复制到如下列表中:

std::list<Rect> sorted_list(boundRect_temp.begin(), boundRect_temp.end());

但是现在我无法访问区域等成员变量。问题是算法不应该太耗时,这就是为什么我在寻找一个好的解决方案。也许已经有了这个功能吗?

2 个答案:

答案 0 :(得分:5)

1)如果将findContours()与CV_RETR_EXTERNAL标志一起使用,则可以过滤大多数交叉点。这意味着不会返回包含在其他轮廓内的轮廓。当然,这不会阻止边界框交叉的所有情况,但这将大大提高后处理的性能

2)载体绝对适合分选。代码简短而有效。并且它比列表更好,因为数据将在内存中连续。

3)从矢量中逐个删除值确实无效,但您不需要这样做。只需创建包含所选框的临时向量,如下所示:

vector < Rect > nonIntersect;
for(unsigned int i=0; i < sortedBoxes.size(); i++) {
    bool toAdd = true;
    Point center = (sortedBoxes[i].tl()+sortedBoxes[i].br())*0.5;
    for(unsigned int j=0; j < nonIntersect.size(); j++)
        if (nonIntersect[j].contains(center)) {
            toAdd = false;
            break;
        }
    if (toAdd)
        nonIntersect.push back(sortedBoxes[i]);
 }

这也可以“就地”完成,但为什么要这么做呢。与原始图像的记忆或findContours找到的轮廓记忆相比,这种记忆是可以忽略的。

答案 1 :(得分:3)

除了michael burdinov所说的,这里按区域排序

struct byArea {
    bool operator () (const Rect & a,const Rect & b) {
         return a.width*a.height < b.width*b.height ;
    }
};

vector<Rect> rects;
std::sort(rects.begin(), rects.end(), byArea());