如何擦除double for循环中的向量元素

时间:2015-04-01 01:51:15

标签: c++ visual-studio opencv vector contour

我有一个struct

的向量
vector<contour> hotspots;

轮廓是我已定义的结构,如下所示

struct contour
{
    double arc;
    double area;
    Point2f center;
    double me;
    double hullArea;
    vector<Point> contourVector;
    vector<Point> hullVector;

    bool operator <(const contour& comp)
    {
        return me < comp.me;
    }
};

所以我想要做的是循环并删除包含在另一个轮廓中的每个轮廓,我可以让它在大多数情况下工作但我有时会得到一个索引错误,我假设它有事情要做当我擦除一个元素时,索引会搞砸,所以我会超出范围。这是我写的循环:

vector<vector<Point>> cleanUp(vector<Point2f> centers, vector<Moments> areas, vector<vector<Point>> contours)
{
    for (int i = 0; i < contours.size(); i++)
        for (int j = 0; j < contours.size(); j++)
            if (i != j)
            {
                if ((areas[i].m00 < areas[j].m00) == true && (pointPolygonTest(contours[j], centers[i], false) > 0) == true)
                {
                    contours.erase(contours.begin() + i);
                    centers.erase(centers.begin() + i);
                    areas.erase(areas.begin() + i);
                }
            }

    return contours;
}

我尝试了一些不同的解决方案,比如i - 1,但删除了错误的轮廓,而不是使用擦除,用最后一个覆盖我要删除的元素,然后使用.pop_back删除最后一个元素但是似乎也没有用。有什么想法吗?

编辑:修复了区域和中心的不同步问题,但现在只要我调用该功能来删除一些轮廓,问题就会立即出现。

2 个答案:

答案 0 :(得分:0)

使用迭代器,我会尝试这种方法:

#include <iterator>

template <typename BinaryPred>
void RemoveIfPairwise(std::vector<T> & v, BinaryPred f)
{
    for (auto it1 = v.begin(); it1 != v.end(); ++it1)
    {
        for (auto it2 = std::next(it1); it2 != v.end(); )
        {
            if (f(*it1, *it2)) { it2 = v.erase(it2); }
            else               { ++it2;              }
        }
    }
}

这使用了std::vector的迭代器非失效保证,例如擦除不会在擦除点之前使迭代器无效(因此it1不需要特殊处理)。

请注意,此循环仅检查不同元素对;你需要修改它以检查对角线。

答案 1 :(得分:0)

您可以保留要删除的项目的索引列表,并删除最后那些索引处的项目。

vector<vector<Point>> cleanUp(vector<Point2f> centers,
                              vector<Moments> areas,
                              vector<vector<Point>> contours)
{
   std::<int> itemsToErase;

    for (int i = 0; i < contours.size(); i++)
        for (int j = 0; j < contours.size(); j++)
            if (i != j)
            {
                if ((areas[i].m00 < areas[j].m00) == true &&
                    (pointPolygonTest(contours[j], centers[i], false) > 0) == true)
                {
                   itemsToErase.push_front(i);
                }
            }

    while  ( !itemsToErase.empty() )
    {
       int i = itemsToErase.back();
       contours.erase(contours.begin() + i);
       centers.erase(centers.begin() + i);
       areas.erase(areas.begin() + i);
       itemsToErase.pop_back();
    }

    return contours;
}
相关问题