使用PCL进行点云交集

5
假设我有两个不同的>(尽管点类型并不重要),c1和c2。
我想找到这两个点云的交集。通过交集,我指的是构建点云inter,使得从c1中插入一个点pi到inter中,当且仅当在c2中存在一个点pj且
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;
}

我想知道是否有一种标准(可能更有效)的方法来做到这一点?

官方文档中我没有找到相关内容,但也许我错过了什么。

谢谢。

2个回答

4

如果你只想寻找确切的匹配,而不是近似匹配,那么可以将每个点云中的点放到一个 std::vector 中,排序后使用 std::set_intersection 来识别匹配项。


谢谢。我唯一担心的是这种方法可能有不同的标签,因此向量应只包含三个空间坐标才能正确比较。这样做,我会失去标签信息,必须重新在原始点云中检索它,再次浏览所有点吧。 - Francesco V.
1
向量可以包含原始点数据。您需要使用自定义比较器,仅使用坐标并忽略标签。 - n. m.
那看起来很合适......我会研究一下的,谢谢! - Francesco V.

1

你的contains函数中寻找点的搜索可以通过使用高效的数据结构,如 KD Tree,使其更加高效。

另一种选择是在管道的早期进行更好的记录,但我们需要更多了解你试图在高层次上实现什么来帮助你。

编辑:正如评论中指出的那样,KD树适用于近似空间搜索,但提问者想要进行精确的点匹配。对于这个问题,哈希表(或其他基本搜索数据结构)可能更有效。


这会加速处理速度,但是这太浪费了。 kD-树不是精确点查询的好结构。它设计用于近似点查询。 - Sneftel
我的高级任务是将我们正在研究的算法计算出的点云分割与给定的真实分割进行比较。 - Francesco V.
1
@FrancescoV。不想偏离原始实现太远,但如果你将其分成两个以上的部分 - 尤其是如果这些部分与地面真值的部分没有先前的关联,则应考虑更正式和强大的统计方法来测量差异。特别是,https://en.wikipedia.org/wiki/Variation_of_information。 - Sneftel
你是对的,Sneftel。哈希表会更直接和更快。 - D.J.Duff
我也在计算VOI,但我想评估精确度、召回率(和F分数);对于这些指标,我需要求交集。 - Francesco V.

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接