基于对应点分类的对象识别
1.本教程旨在说明如何基于pcl_recognition模块执行3D对象识别。具体来说,它解释了如何使用对应分组算法,以便将在3D描述符匹配阶段之后获得的点对点对应关系集聚为当前场景中存在的模型实例。对于表示场景中可能的模型实例的每个聚类,对应分组算法还输出标识当前场景中该模型的6DOF姿态估计的变换矩阵。
2.小bug
[pcl::SHOTEstimation::computeFeature] The local reference frame is not valid! Aborting description of point with index 3045这个错误是由于正常半径较小的事实,一些法线是NaN(在设置半径的球体内它们的邻域中没有点),这些原因导致SHOT出现问题。
3.代码
#include <pcl/io/pcd_io.h>
#include <pcl/point_cloud.h>
#include <pcl/correspondence.h>
#include <pcl/features/normal_3d_omp.h>
#include <pcl/features/shot_omp.h>
#include <pcl/features/board.h>
#include <pcl/filters/uniform_sampling.h>
#include <pcl/recognition/cg/hough_3d.h>
#include <pcl/recognition/cg/geometric_consistency.h>
#include <pcl/visualization/pcl_visualizer.h>
#include <pcl/kdtree/kdtree_flann.h>
//#include <pcl/kdtree/impl/kdtree_flann.hpp>
#include <pcl/common/transforms.h>
#include <pcl/console/parse.h>
typedef pcl::PointXYZRGBA PointType;
typedef pcl::Normal NormalType;
typedef pcl::ReferenceFrame RFType;
typedef pcl::SHOT352 DescriptorType;
std::string model_filename_;//模型文件
std::string scene_filename_;//场景文件
//Algorithm params
bool show_keypoints_(false);//显示关键点
bool show_correspondences_(false);//显示对应点
bool use_cloud_resolution_(false);//利用-r选项控制,如果设置为真,所有参数将与点云分辨率相乘得到最终使用的参数
bool use_hough_(true);//默认算法为Hough 3D Grouping
float model_ss_(0.01f);//模型均匀采样的搜索半径0.01f
float scene_ss_(0.03f);//场景均匀采样的搜索半径0.03f
float rf_rad_(0.015f);//参考坐标系的半径0.015f
float descr_rad_(0.02f);//0.02f改20.0f[pcl::SHOTEstimation::computeFeature] The local reference frame is not valid! Aborting description of point with index 3045
float cg_size_(0.01f);//聚类大小0.01f
float cg_thresh_(5.0f);//聚类阈值5.0
void
showHelp(char *filename)
{
std::cout << std::endl;
std::cout << "***************************************************************************" << std::endl;
std::cout << "* *" << std::endl;
std::cout << "* Correspondence Grouping Tutorial - Usage Guide *" << std::endl;
std::cout << "* *" << std::endl;
std::cout << "***************************************************************************" << std::endl << std::endl;
std::cout << "Usage: " << filename << " model_filename.pcd scene_filename.pcd [Options]" << std::endl << std::endl;
std::cout << "Options:" << std::endl;
std::cout << " -h: Show this help." << std::endl;
std::cout << " -k: Show used keypoints." << std::endl;
std::cout << " -c: Show used correspondences." << std::endl;
std::cout << " -r: Compute the model cloud resolution and multiply" << std::endl;
std::cout << " each radius given by that value." << std::endl;
std::cout << " --algorithm (Hough|GC): Clustering algorithm used (default Hough)." << std::endl;
std::cout << " --model_ss val: Model uniform sampling radius (default 0.01)" << std::endl;
std::cout << " --scene_ss val: Scene uniform sampling radius (default 0.03)" << std::endl;
std::cout << " --rf_rad val: Reference frame radius (default 0.015)" << std::endl;
std::cout << " --descr_rad val: Descriptor radius (default 0.02)" << std::endl;
std::cout << " --cg_size val: Cluster size (default 0.01)" << std::endl;
std::cout << " --cg_thresh val: Clustering threshold (default 5)" << std::endl << std::endl;
}
void
parseCommandLine(int argc, char *argv[])
{
//Show help
if (pcl::console::find_switch(argc, argv, "-h"))
{
showHelp(argv[0]);
exit(0);
}
//Model & scene filenames
std::vector<int> filenames;
filenames = pcl::console::parse_file_extension_argument(argc, argv, ".pcd");
if (filenames.size() != 2)
{
std::cout << "Filenames missing.\n";
showHelp(argv[0]);
exit(-1);
}
model_filename_ = argv[filenames[0]];//命令行的第二个参数赋值给model_filename
scene_filename_ = argv[filenames[1]];//命令行的第三个参数解析为scene_filename
//Program behavior
if (pcl::console::find_switch(argc, argv, "-k"))
{
show_keypoints_ = true;
}
if (pcl::console::find_switch(argc, argv, "-c"))
{