我有一个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删除最后一个元素但是似乎也没有用。有什么想法吗?
编辑:修复了区域和中心的不同步问题,但现在只要我调用该功能来删除一些轮廓,问题就会立即出现。
答案 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;
}