稀疏点云分割全过程(点云滤波去除重复点)
稀疏点云分割全过程(点云滤波去除重复点)我一般都是把程序写成一个 算子functor,然后适配我的可视化平台:然后就是C 代码基本功。采样去重学会写 操作算子,扩展pcl的库代码。其中有几个注意点:
在 pcl库 <pcl/filters/random_sample.h> 的RandomSample 会产生重复点 需要去除重复点。
主要是利用 集合的功能去除 重复的点
using namespace pcl;
namespace std{
template <>
struct hash<pcl::PointXYZ> //支持字典hash
{
std::hash<float> h;
size_t operator()(const pcl::PointXYZ& k) const noexcept
{
return h(k.x 11) * h(k.y 13) h(k.z 17);
}
};
}
namespace pcl {
inline bool operator==(const PointXYZ& p1 const PointXYZ& p2)
{
return p1.x == p2.x && p1.y == p2.y && p1.z == p2.z;
}
}
struct OpCldRmReplicatePoint
{
std::unordered_set<PointXYZ> ptSet;
PointIndices ptIndices;
PointXYZ _pt;
template<class PT>
pcl::shared_ptr<PointCloud<PT>> operator()(const pcl::shared_ptr<PointCloud<PT> >& cld)
{
auto& pts = cld->points;
auto res = pcl::make_shared<PointCloud<PT>>();
if (pts.empty())
return res;
auto& indices = ptIndices.indices;
ptSet.clear();
indices.clear();
for (int i = 0; i< pts.size(); i)
{
auto& pt = pts[i];
_pt.x = pt.x;
_pt.y = pt.y;
_pt.z = pt.z;
if(ptSet.find(_pt) != ptSet.end())
continue;
ptSet.insert(_pt);
indices.push_back(i);
}
pcl::copyPointCloud(*cld ptIndices *res);
return res;
}
};
主要是 实现了 PointXYZ的 operator==、hash函数,让它支持 unordered_set.
编写成算子,在可视化平台加载
采样去重
学会写 操作算子,扩展pcl的库代码。
其中有几个注意点:
- 浮点数是可以进行 直接 ==比较的,因为不存在舍入误差,没必要定义 fabs(v1-v2) < eps等操作
- 需要注意 重载 std::hash时候,需要在std空间定义偏特化函数。
- 定义 operator==时候,需要在pcl空间定义 函数
然后就是C 代码基本功。
我一般都是把程序写成一个 算子functor,然后适配我的可视化平台:
适配插件的代码
插件描述
编译成 KPclOpCldRmReplicatePoint.dll 文件
加载到插件目录
然后就可以直接 可视化插件测试。