欢迎点云相关产学研的学者和团体加入我们。
首先加载对象的模板点云,已经将的模板点云保存为.PCD文件,并且已经在object_templates.txt文件中列出了所有模板文件的名字,这里,读入每个文件的名字,加载到FeatureCloud,并且将FeatureCloud存储成矢量在后面使用。
//从object_templates.txt加载模板点云文件
std::vector<FeatureCloud> object_templates;
std::ifstreaminput_stream (argv[1]);
object_templates.resize (0);
std::string pcd_filename;
while (input_stream.good ())
{
std::getline (input_stream, pcd_filename);
if (pcd_filename.empty () || pcd_filename.at (0) =='#')
//跳过空行或注释(#开头的行)
continue;
FeatureCloudtemplate_cloud;
template_cloud.loadInputCloud (pcd_filename);
object_templates.push_back (template_cloud);
}
input_stream.close ();
接下来加载目标云。
//获取目标点云
pcl::PointCloud<pcl::PointXYZ>::Ptr cloud (new pcl::PointCloud<pcl::PointXYZ>);
pcl::io::loadPCDFile (argv[2], *cloud);
然后对数据进行一些预处理以便为配准做准备,第一步就是过滤掉一些噪声点和冗余数据,在这个例子中,假设这个我们试图配准的人在距离不到1米处,所以就应用一个直通的过滤器,过滤领域的“z”(即,深度)与范围为0到1。
// 预处理点云
// 删除距离较远的冗余点
constfloatdepth_limit=1.0;
pcl::PassThrough<pcl::PointXYZ> pass;
pass.setInputCloud (cloud);
pass.setFilterFieldName ("z");
pass.setFilterLimits (0, depth_limit);
pass.filter (*cloud);
下面是利用5cm的体素栅格对目标点云进行下采样,这样可以减少运算量。
// ... 对点云进行下采样
const floatvoxel_grid_size=0.005f;
pcl::VoxelGrid<pcl::PointXYZ> vox_grid;
vox_grid.setInputCloud (cloud);
vox_grid.setLeafSize (voxel_grid_size, voxel_grid_size, voxel_grid_size);
vox_grid.filter (*cloud);
在预处理结束后,创建FeatureCloud目标对象。
// 设置目标点云为FeatureCloud对象输入点云
FeatureCloudtarget_cloud;
target_cloud.setInputCloud (cloud);
接下来,初始化TemplateAlignment对象,这一步需要添加每个我们的点云模板并且设置目标云。
// 设置TemplateAlignment输入点云
TemplateAlignmenttemplate_align;
for (size_t i=0; i<object_templates.size (); ++i)
{
template_align.addTemplateCloud (object_templates[i]);
}
template_align.setTargetCloud (target_cloud);
现在TemplateAlignment目标对象被初始化了,我们准备用findBestAlignment方法来决定哪一个模板是给出目标云的最佳匹配模板点云,我们将配准结果保存到best_alignment。
// 寻找最佳匹配模板点云
TemplateAlignment::Result best_alignment;
int best_index=template_align.findBestAlignment (best_alignment);
const FeatureCloud&best_template=object_templates[best_index];
未完待续,敬请关注“对齐对象模板到点云(5)”的其他内容。