问题
I am trying to match features between two point cloud I test by changing many parameters but it always produces wrong matches. I am calculating PFH feature descriptors of SIFT features.
Thank you for your suggestions.
Below is the code I used
// load the both point clouds
pcl::io::loadPCDFile("Tee.pcd", *cloud_1);
pcl::PLYReader Reader;
Reader.read("tee.ply", *cloud_2);
//pcl::io::loadPCDFile("Tee.pcd", *cloud_2);
// Create the filtering object
pcl::PassThrough<pcl::PointXYZRGB> pass;
pass.setInputCloud(cloud_2);
pass.setFilterFieldName("z");
pass.setFilterLimits(0.0, 1.0);
//pass.setFilterLimitsNegative (true);
pass.filter(*cloud_2_filtered);
// Downsample the cloud
const float voxel_grid_leaf_size = 0.009f;
downsample(cloud_1, voxel_grid_leaf_size, downsampledCloud_1);
std::cout << "First cloud: downsampled " << std::endl;
const float voxel_grid_leaf_size2 = 0.003f;
downsample(cloud_2_filtered, voxel_grid_leaf_size2, downsampledCloud_2);
std::cout << "second cloud: downsampled " << std::endl;
// Compute surface normals
const float normal_radius = 0.03;
compute_surface_normals(downsampledCloud_1, normal_radius, normalsFromCloud_1);
compute_surface_normals(downsampledCloud_2, normal_radius, normalsFromCloud_2);
std::cout << "second cloud: normals computed " << std::endl;
// Compute keypoints
const float min_scale = 0.01;
const int nr_octaves = 3;
const int nr_octaves_per_scale = 6;
const float min_contrast = 1.0;
detect_keypoints(cloud_1, min_scale, nr_octaves, nr_octaves_per_scale, min_contrast, keypointsFromCloud_1);
std::cout << "first cloud: keypoints computed " << std::endl;
//const float min_scale1 = 0.1;
detect_keypoints(cloud_2_filtered, min_scale, nr_octaves, nr_octaves_per_scale, min_contrast, keypointsFromCloud_2);
std::cout << "second cloud: keypoints computed " << std::endl;
//visualize_keypoints(cloud_2, keypointsFromCloud_2);
// Compute PFH features
const float feature_radius = 0.08;
compute_PFH_features_at_keypoints(downsampledCloud_1, normalsFromCloud_1, keypointsFromCloud_1, feature_radius, descriptors1);
std::cout << "first cloud: descriptor computed " << std::endl;
compute_PFH_features_at_keypoints(downsampledCloud_2, normalsFromCloud_2, keypointsFromCloud_2, feature_radius, descriptors2);
std::cout << "second cloud: descriptor computed " << std::endl;
// Find feature correspondences
std::vector<int> correspondences;
std::vector<float> correspondence_scores;
find_feature_correspondences(descriptors1, descriptors2, correspondences, correspondence_scores);
// Print out ( number of keypoints / number of points )
std::cout << "First cloud: Found " << keypointsFromCloud_1->size() << " keypoints "
<< "out of " << downsampledCloud_1->size() << " total points." << std::endl;
std::cout << "Second cloud: Found " << keypointsFromCloud_2->size() << " keypoints "
<< "out of " << downsampledCloud_2->size() << " total points." << std::endl;
// Visualize the two point clouds and their feature correspondences
visualize_correspondences(cloud_1, keypointsFromCloud_1, cloud_2_filtered, keypointsFromCloud_2, correspondences, correspondence_scores);
The resulting image is as shown:
回答1:
Data & Preprocessing
It seems like that you are trying to match a point cloud with only the object to a point cloud where the object is inside the scene.
In order to get consistent and robust results, extract all object from the scene beforehand and try to match the reference to all detected objects and select the best match.
Descriptor
I experienced way better results using the SHOT descriptor rather than PFH.
Here you can read more on Object Recognition from the authors of PCL where they describe and explain the whole pipeline for object recognition.
来源:https://stackoverflow.com/questions/53837234/pcl-feature-matching-failure