point-clouds - 以有效的方式将点从一个 PCL 移到另一个
问题描述
有类似的问题,但我主要关心的是处理时间。
我有两个 PCL,都是 type pcl::PointXYZL
,也就是说,每个点都有一个标签/id 信息。我想在 PC B 中删除 A 中存在的所有点(由标签信息识别)。
这种类型的迭代需要太多时间。
我决定将标签从 PC A 保存到boost::container::flat_set<int> labels
,并将云 B 设置为std::map<int, pcl::PointXYZL> cloud_B
,其中键是该点的标签/ID。然后我这样做:
for(boost::container::flat_set<int>::iterator it = labels.begin() ; it != labels.end(); ++it){
if ( auto point{ cloud_B.find( *it ) }; point != std::end(cloud_B)){
cloud_B.erase(*it);
}
}
它现在要快得多,但老实说,我认为可能有更有效的解决方案。
我也尝试:
for(boost::container::flat_set<int>::iterator it = labels.begin() ; it != labels.end(); ++it){
try{
cloud_B.erase(*it);
throw 505;
}
catch (...){
continue;
}
}
但这比我带来的第一个例子要花更多的时间。
我感谢任何帮助!
解决方案
您的两个解决方案都大致为 O(n^2) 复杂度。
用于unordered_set<std::uint32_t>
检查它是否存在。的平均情况unordered_set<std::uint32_t>::count
是恒定的,因此它应该比您的解决方案更好
示例代码(未经测试),但你得到了粗略的想法。
pcl::PointCloud<pcl::PointXYZL> cloud_a;
pcl::PointCloud<pcl::PointXYZL> cloud_b;
... (fill cloud)
// generate unordered_set<uint32_t> O(n)
std::unordered_set<std::uint32_t> labels_in_cloud_a;
for (int i = 0; i < cloud_a.size(); ++i) {
labels_in_cloud_a.insert(cloud_a.points[i].label);
}
// indices where in cloud_b where label doesn't exist in labels_in_clouda O(n*1) = O(n)
std::vector<int> indices;
for (int i = 0; i < cloud_b.size(); ++i) {
if (labels_in_cloud_a.count(cloud_b.points[i].label) == 0) {
indices.push_back(i);
}
}
// only indices that doesn't exist in cloud_a will remain. O(n)
pcl::copyPointCloud(cloud_b, indices, cloud_b);
推荐阅读
- bootstrap-4 - 如何通过先前选择的项目 ID 填充下拉列表
- css - 如何告诉 Stylus 不要将 CSS 属性解释为 mixin?
- python - 如何创建基于资源的策略?
- excel - 在字符串 VBA 中搜索数字
- azure - 互联网出口的 Kubernetes 网络策略
- node.js - Mongoose find() 并追加到数组
- google-cloud-platform - GCloud 计算实例停止但未停止
- ios - iOS 13 UIViewController 模态演示阴影
- kubernetes-helm - 如何将 istio 注入到使用 helm 部署的部署中
- python - os.path.dirname 和 os.path.join