基于VFH描述子的聚类识别与6自由度位姿估计的学习

        本次学习中,我们的目标不是提供一个最终的识别工具,而是根据各个聚类的场景及其对应的6自由度位姿,从一组聚类中检索查询进而选取与用户输入的场景近似的候选集,这样就可以将识别问题抽象为一个近邻估计问题。给定一组训练数据,我们将使用一种有效的近邻搜索结构,例如kdtree,来查找返回一组相似对象,这些相似对象以与查找对象之间的距离来进行排序,很明显这样的程序要比直接返回是否存在用户检索的场景的程序要更有用处。具体内容可参考http://www.pclcn.org/study/shownews.php?lang=cn&id=188的学习教程。

         1.训练阶段,build_tree.cpp

#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
{
sensor_msgs::PointCloud2 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 (pcl::InvalidConversionException e)
{
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 <sensor_msgs::PointField> fields;
pcl::getFieldIndex (point, "vfh", fields);

for (size_t i = 0; i < fields[vfh_idx].count; ++i)
{
vfh.second[i] = point.points[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 (m);
}
}
}

int
main (int argc, char** argv)
{
if (argc < 2)
{
PCL_ERROR ("Need at least two parameters! Syntax is: %s [model_directory] [options]\n", argv[0]);
return (-1);
}

std::string extension (".pcd");
transform (extension.begin (), extension.end (), extension.begin (), (int(*)(int))tolower);

std::string kdtree_idx_file_name = "kdtree.idx";
std::string training_data_h5_file_name = "training_data.h
  • 1
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
在PCL中,可以通过以下步骤进行二值化描述的特征匹配: 1. 计算描述:使用PCL中提供的特征估计器计算点云的描述,例如VFH、FPFH、SHOT、3DSC、CVFH等。 2. 二值化描述:将计算出的描述进行二值化操作,将每个直方图的值转换为0或1。可以使用简单的阈值或其他二值化方法来实现。 3. 特征匹配:使用PCL中提供的对应估计器对二值化描述进行特征匹配。例如,可以使用CorrespondenceEstimation类或者SampleConsensusInitialAlignment类来进行匹配。 4. 输出匹配结果:将匹配结果输出,可以通过对应关系来找到匹配点对应的索引。 下面是一个使用VFH描述和CorrespondenceEstimation类进行二值化描述特征匹配的示例代码: ```c++ #include <iostream> #include <pcl/point_cloud.h> #include <pcl/features/fpfh.h> #include <pcl/features/feature.h> #include <pcl/features/pfh.h> #include <pcl/features/shot.h> #include <pcl/features/shot_omp.h> #include <pcl/features/3dsc.h> #include <pcl/features/cvfh.h> #include <pcl/features/our_cvfh.h> #include <pcl/registration/correspondence_estimation.h> int main(int argc, char** argv) { // 加载点云数据 pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>); pcl::io::loadPCDFile<pcl::PointXYZ>("cloud.pcd", *cloud); // 计算VFH描述 pcl::PointCloud<pcl::VFHSignature308>::Ptr descriptors(new pcl::PointCloud<pcl::VFHSignature308>); pcl::VFHEstimation<pcl::PointXYZ, pcl::Normal, pcl::VFHSignature308> vfh; pcl::NormalEstimation<pcl::PointXYZ, pcl::Normal> ne; pcl::search::KdTree<pcl::PointXYZ>::Ptr tree(new pcl::search::KdTree<pcl::PointXYZ>); ne.setInputCloud(cloud); ne.setSearchMethod(tree); pcl::PointCloud<pcl::Normal>::Ptr cloud_normals(new pcl::PointCloud<pcl::Normal>); ne.setRadiusSearch(0.03); ne.compute(*cloud_normals); vfh.setInputCloud(cloud); vfh.setInputNormals(cloud_normals); vfh.setSearchMethod(tree); vfh.compute(*descriptors); // 二值化VFH描述 pcl::PointCloud<pcl::VFHSignature308>::Ptr binary_descriptors(new pcl::PointCloud<pcl::VFHSignature308>); for (int i = 0; i < descriptors->size(); i++) { pcl::VFHSignature308 descriptor = descriptors->points[i]; pcl::VFHSignature308 binary_descriptor; for (int j = 0; j < 308; j++) { binary_descriptor.histogram[j] = (descriptor.histogram[j] > 0.5) ? 1 : 0; } binary_descriptors->push_back(binary_descriptor); } // 特征匹配 pcl::CorrespondencesPtr correspondences(new pcl::Correspondences); pcl::registration::CorrespondenceEstimation<pcl::VFHSignature308, pcl::VFHSignature308> est; est.setInputSource(binary_descriptors); est.setInputTarget(binary_descriptors); est.determineCorrespondences(*correspondences); // 输出匹配结果 for (int i = 0; i < correspondences->size(); i++) { pcl::Correspondence correspondence = correspondences->at(i); std::cout << "source index: " << correspondence.index_query << ", target index: " << correspondence.index_match << std::endl; } return 0; } ``` 在上述代码中,使用VFH描述计算点云特征,并通过简单的阈值将其转换为二值化描述。然后使用CorrespondenceEstimation类进行特征匹配,并输出匹配结果。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值