基于PCL的物体识别与位姿估计tutorial学习

基于PCL的物体识别与位姿估计tutorial学习

本篇来源PCL点云库的tutorial。该tutorial的大致思想是将点云用VFH特征进行描述,然后训练生成树模型,当给一个新点云,计算其VFH,通过最邻近搜索,找到最相似的点云模型,完成识别。



前言

物体识别这块应用非常广泛,相关的方法也比较多。这个tutorial给pcl特征描述子一个应用的方法,至少让我知道库里面的特征描述子都有那些应用。pcl库比opencv库容易很多,用起来上手很快。编译这个tutorial不容易,特此记录一下,帮助将来的学习者。第一部分先介绍如何编译,第二部分再对代码进行剖析(未完待续)。


一、编译步骤

pcl库的安装不介绍,我不是源码编译安装的,直接装的二进制。这个例子需要安装HDF5,按照这个链接步骤,亲测有效。但是安装完用PCL官网的CMakeLists还是没有办法通过编译。其中用到find_package(),来找到HFD5这个库。但我本地usr/share/make-3.10/Module的FindHDF5.cmake,可能有点问题,不能用这个方法。所以我是手动设置头文件和库文件的地址,见CMakeLists.txt。

然后是FLANN这个库的FindFLANN.cmake这个文件,我的cmake,Module里面没有这个文件,从这个flann库的github源码地方,把这个文件找到,丢到cmake,Module里面,find_package()这个命令就可以用了。我本地FLANN库头文件位置倒是清楚,库文件位置我不太确定。

另外,有了上述的库,我自己编译时,还遇到一个错误,如下图所示。一开始,我以为是我前面的步骤错了,后来看到有人分享这个错误与mpi_cxx 有关。在这里插入图片描述

把这个库,链接上就可以编译运行了。

我的CMakeLists.txt文件如下:

cmake_minimum_required(VERSION 2.8 FATAL_ERROR)

#设置可执行文件放到bin下
set(EXECUTABLE_OUTPUT_PATH ${PROJECT_BINARY_DIR}/../bin)

# we need FindFLANN.cmake 

list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR})
project(vfh_cluster_classifier)
find_package(PCL 1.8 REQUIRED)
include_directories(
	${PCL_INCLUDE_DIRS}
)

link_directories(${PCL_LIBRARY_DIRS})
add_definitions(${PCL_DEFINITIONS})

#可以先试试,能不能用
#find_package(HDF5)
find_package(FLANN REQUIRED)

include_directories(${FLANN_INCLUDE_DIRS})
  
#手动设置头文件地址与库文件地址
include_directories(${HDF5_INCLUDE_DIR} /usr/local/hdf5/include)
set(${HDF5_LIBRARIES} /usr/local/hdf5/lib)

  add_executable(build_tree src/build_tree.cpp)
  target_link_libraries(build_tree 
  ${PCL_LIBRARIES}
  mpi_cxx 
  ${Boost_LIBRARIES}
  ${FLANN_LIBRARIES}                              
  ${HDF5_LIBRARIES}
)

  add_executable(nearest_neighbors src/nearest_neighbors.cpp)
  target_link_libraries(nearest_neighbors 
  	${PCL_LIBRARIES} 
  	mpi_cxx 
  	${Boost_LIBRARIES} 
	${FLANN_LIBRARIES} 
	${HDF5_LIBRARIES} 
)

二、使用步骤

1.训练阶段

代码如下:

#include <pcl/point_types.h>
#include <pcl/point_cloud.h>
#include <pcl/console/parse.h>
#include <pcl/console/print.h>
#include <pcl/io/pcd_io.h>
#include <boost/filesystem.hpp>
#include <flann/flann.h>
#include <flann/io/hdf5.h>
#include <fstream>

typedef std::pair<std::string, std::vector<float> > vfh_model;

/** \brief Loads an n-D histogram file as a VFH signature
  * \param path the input file name
  * \param vfh the resultant VFH model
  */
bool
loadHist (const boost::filesystem::path &path, vfh_model &vfh)
{
   
  int vfh_idx;
  // Load the file as a PCD
  try
  {
   
    pcl::PCLPointCloud2 cloud;
    int version;
    Eigen::Vector4f origin;
    Eigen::Quaternionf orientation;
    pcl::PCDReader r;
    int type; unsigned int idx;
    r.readHeader (path.string (), cloud, origin, orientation, version, type, idx);

    vfh_idx = pcl::getFieldIndex (cloud, "vfh");
    if (vfh_idx == -1)
      return (false);
    if ((int)cloud.width * cloud.height != 1)
      return (false);
  }
  catch (const pcl::InvalidConversionException&)
  {
   
    return (false);
  }

  // Treat the VFH signature as a single Point Cloud
  pcl::PointCloud <pcl::VFHSignature308> point;
  pcl::io::loadPCDFile (path.string (), point);
  vfh.second.resize (308);

  std::vector <pcl::PCLPointField> fields;
  pcl::getFieldIndex<pcl::VFHSignature308> ("vfh", fields);

  for (std::size_t i = 0; i < fields[vfh_idx].count; ++i)
  {
   
    vfh.second[i] = point[0].histogram[i];
  }
  vfh.first = path.string ();
  return (true);
}

/** \brief Load a set of VFH features that will act as the model (training data)
  * \param argc the number of arguments (pass from main ())
  * \param argv the actual command line arguments (pass from main ())
  * \param extension the file extension containing the VFH features
  * \param models the resultant vector of histogram models
  */
void
loadFeatureModels (const boost::filesystem::path &base_dir, const std::string &extension, 
                   std::vector<vfh_model> &models)
{
   
  if (!boost::filesystem::exists (base_dir) && !boost::filesystem::is_directory (base_dir))
    return;

  for (boost::filesystem::directory_iterator it (base_dir); it != boost::filesystem::directory_iterator (); ++it)
  {
   
    if (boost::filesystem::is_directory (it->status ()))
    {
   
      std::stringstream ss;
      ss << it->path ();
      pcl::console::print_highlight ("Loading %s (%lu models loaded so far).\n", ss.str ().c_str (), (unsigned long)models.size ());
      loadFeatureModels (it->path (), extension, models);
    }
    if (boost::filesystem::is_regular_file (it->status ()) && boost::filesystem::extension (it->path ()) == extension)
    {
   
      vfh_model m;
      if (loadHist (base_dir / it->path ().filename (), m))
        models.push_back
  • 0
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值