VFH(Viewpoint Feature Histogram)描述子應用於點雲聚類識別和六自由度位姿估計問題
(1)訓練
給定一個只包含一個物體的場景,這樣方便后面聚類的得到。利用一個准確的位姿記錄系統獲取位姿。獲取的不同視角的點雲計算VFH描述子。
保存不同視角的點雲,並基於此建立kdtree。
(2)測試
從給定的場景中分割提取出聚類。對於每個聚類,計算其VFH描述子。利用VFH描述子在上面建立的kdtree進行搜索查找。
VFH利用了FPFH特征優異的識別能力,同時引入視點變量以使其不受尺度變化影響,VFH是對整個點雲進行處理的(輸出結果只有一個直方圖)。
VFH特征包含兩部分:
1.viewpoint direction component
計算視點方向和所有點的法向的夾角的直方圖(視點方向平移到每個點處)
2.extened FPFH component
measure between the viewpoint direction at the centroid point and each of the normals on the surface.

// load point cloud pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>); pcl::io::loadPCDFile("D:\\pcd\\rabbit.pcd", *cloud); cout << "points size:" << cloud->points.size() << endl; clock_t t3 = clock(); pcl::NormalEstimation<pcl::PointXYZ, pcl::Normal> ne; ne.setInputCloud(cloud); pcl::search::KdTree<pcl::PointXYZ>::Ptr tree(new pcl::search::KdTree<pcl::PointXYZ>()); ne.setSearchMethod(tree); pcl::PointCloud<pcl::Normal>::Ptr cloud_normals(new pcl::PointCloud<pcl::Normal>); ne.setKSearch(5); //ne.setRadiusSearch(0.03); ne.compute(*cloud_normals); clock_t t4 = clock(); double time = (double)(t4 - t3) / CLOCKS_PER_SEC; cout << "calc normal time:" << time << endl; pcl::VFHEstimation<pcl::PointXYZ, pcl::Normal, pcl::VFHSignature308> vfh; vfh.setInputCloud(cloud); vfh.setInputNormals(cloud_normals); vfh.setViewPoint(0, 0, 10000); pcl::search::KdTree<pcl::PointXYZ>::Ptr tree1(new pcl::search::KdTree<pcl::PointXYZ>); vfh.setSearchMethod(tree1); pcl::PointCloud<pcl::VFHSignature308>::Ptr vfhs(new pcl::PointCloud<pcl::VFHSignature308>()); vfh.compute(*vfhs); //定義繪圖器 pcl::visualization::PCLPlotter *plotter = new pcl::visualization::PCLPlotter("My Plotter"); //設置特性 plotter->setShowLegend(true); std::cout << pcl::getFieldsList<pcl::VFHSignature308>(*vfhs); //顯示 plotter->addFeatureHistogram<pcl::VFHSignature308>(*vfhs, "vfh", 0, "vfh"); plotter->setWindowSize(800, 600); plotter->spinOnce(30000); plotter->clearPlots();