使用 PCL 点云的交集

Intersection of PointClouds using PCL

假设我有两个不同的 pcl::PointCloud<pcl::PointXYZL>(尽管点类型并不重要),c1c2

我想找到这两个点云的交集。 通过交集,我的意思是点云 inter 构造使得 c1 中的点 pi 插入 inter 如果(且仅当)点 pj 存在于c2

pi.x == pj.x && pi.y == pj.y && pi.z == pj.z

目前我正在使用以下函数来实现此目的:

#include <pcl/point_cloud.h>
#include <pcl/point_types.h>

using namespace pcl;

typedef PointXYZL PointLT;
typedef PointCloud<PointLT> PointLCloudT;

bool contains(PointLCloudT::Ptr c, PointLT p) {
    PointLCloudT::iterator it = c->begin();
    for (; it != c->end(); ++it) {
        if (it->x == p.x && it->y == p.y && it->z == p.z)
            return true;
    }
    return false;
}

PointLCloudT::Ptr intersection(PointLCloudT::Ptr c1,
        PointLCloudT::Ptr c2) {
    PointLCloudT::Ptr inter;
    PointLCloudT::iterator it = c1->begin();
    for (; it != c1->end(); ++it) {
        if (contains(c2, *it))
            inter->push_back(*it);
    }

    return inter;
}

我想知道是否有标准(并且可能更有效)的方法来执行此操作?

我在 official documentation 中没有找到关于此的任何信息,但也许我遗漏了什么。

谢谢。

如果您只是寻找精确匹配,而不是近似匹配,您可以简单地将每个点云中的点放在 std::vector 中,对其进行排序,然后使用 std::set_intersection 来识别匹配项。

通过使用像 KD Tree.

这样的高效数据结构,可以使 contains 函数中的点搜索更加高效

另一种选择是在您的管道中更早地进行更好的簿记,但我们需要更多地了解您在高层次上想要实现的目标,以帮助您实现这一目标。

编辑:正如评论中指出的那样,KD Tree 适用于近似空间搜索,但提问者想要进行精确的点匹配。为此,散列 table(或其他一些基本搜索数据结构)可能更有效。