根据点对之间的距离从矢量中移除点

时间:2016-08-01 07:49:23

标签: c++ lambda

我的cv::Point点矢量是x,y坐标。如果它们彼此太靠近,我想移除点,例如< 20.我无法正确编写lambda函数。

std::vector<cv::Point> points(5);
points[0] = cv::Point(150, -700); // some random values
points[0] = cv::Point(146, -710);
points[0] = cv::Point(600, -500);
points[0] = cv::Point(140, -500);
points[0] = cv::Point(150, -550);

points.erase(std::remove_if(points.begin(), points.end(),
    [](cv::Point pt1, cv::Point pt2)
    {
        return sqrt(pow(pt2.x-pt1.x,2)+pow(pt2.y-pt1.y,2));
    }), points.end());

问题出在lambda函数的参数中。如果我指定了两个cv :: Point参数,如上所示,则存在编译错误。如果我只是在(cv::Point pt1)中指定一个参数,那么它编译得很好但是我无法访问第二个点。

我将如何解决这个问题?

编辑:

  1. 很抱歉缺少信息。这里有更多细节: 如果v = [a b c d e]元素是由x,y坐标值和b和c组成的2d点彼此非常接近,那么我想删除c,如下所示:v = [a b d e]

  2. 我从一个我无法控制的不同过程中获取向量,因此我无法验证距离并阻止其插入向量

2 个答案:

答案 0 :(得分:0)

正如其他人指出Humam的答案中的缺陷,这是另一种方法:

unsigned nb_removed = 0;
for (int i = 0; i < points.size() - nb_removed; ++i) {
    for (auto j = i + 1; j < points.size() - nb_removed; ++j) {
        if (cv::norm(points[i] - points[j]) < 20) {
            std::iter_swap(points.begin() + i, points.end() - nb_removed - 1));
            std::iter_swap(points.begin() + j, points.end() - nb_removed - 2));
            nb_removed += 2;
            --i;
            break;
        }
    }
}
points.erase(points.end() -nb_removed, points.end());

请注意,这将删除两个彼此接近的点。因此,例如,如果你有 p1,p2,p3 ,那么 d(p1,p2)&lt; 20 d(p2,p3)&lt; 20,然后 p1 p2 将被删除,但 p3 将保持不变。如果这是你想要的行为,那么像上面那样的简单循环无法解决这个问题。我会建议更详细的数据结构,如KD-trees来处理这种情况

答案 1 :(得分:0)

我改编了Rerito的答案; 您希望删除彼此接近的点之一小于给定的阈值距离,并且假设您要从向量中删除较小值的元素。您可以使用以下代码;

unsigned nb_removed = 0;
int threshold_distance = 5;

for (int i = 0; i < V.size() - nb_removed; ++i) {
    for (auto j = i + 1; j < V.size() - nb_removed; ++j) {

        if (abs(V[i] - V[j]) < threshold_distance) {

            if (V[i] < V[j]){
                std::iter_swap(V.begin() + i, V.end() - nb_removed - 1);
                nb_removed += 1;
                --i;
                break;
            }else{
                std::iter_swap(V.begin() + j, V.end() - nb_removed - 1);
                nb_removed += 1;
                --j;
                break;
            }
        }
    }
}
V.erase(V.end() -nb_removed, V.end());
cout << "after process: \n";
for (int i=0; i<V.size(); i++)
 cout<< V[i] << " - ";
cout << endl;

下面给出了一个示例输出。

在处理矢量元素之前:

1 - 11 - 33 - 30 - 10 - 2 - 112 - 111 - 199 - 211

在处理矢量元素之后:

211 - 11 - 33 - 112 - 199 - 2