void cloud_cb(const sensor_msgs::PointCloud2::ConstPtr& cloud_msg) { // Print cloud message if(print_msgs) print_cloud_msg(cloud_msg); // Extract RGB image from cloud cv::Mat img; extract_rgb_image(cloud_msg, img); // Detect keypoints from RGB image std::vector<cv::KeyPoint> keypoints; extract_keypoints(img, keypoints); // Build feature cloud from keypoints sensor_msgs::PointCloud2::Ptr feature_cloud_msg(new sensor_msgs::PointCloud2); build_feature_cloud(keypoints, cloud_msg, feature_cloud_msg); // Publish the data pub_cloud.publish(feature_cloud_msg); }
// global variables used: NONE void vtree_user::compute_features( pcl::PointCloud<PointT>::Ptr & point_cloud, pcl::PointCloud<PointT>::Ptr & keypoints, pcl::PointCloud<FeatureType>::Ptr & features ) { // Define Parameters // IMPORTANT: the radius used for features has to be larger than the radius used to estimate the surface normals!!! #if FEATURE == 1 // FPFH float keypoint_radius_(0.032f); float normal_radius_(0.04f); float feature_radius_(0.063f); #elif FEATURE == 2 // PFH float keypoint_radius_(0.02f); float normal_radius_(0.03f); float feature_radius_(0.04f); #elif FEATURE == 3 // VFH float keypoint_radius_(0.02f); float normal_radius_(0.03f); float feature_radius_(0.04f); #endif ROS_INFO("[vtree_user] Starting keypoint extraction..."); clock_t tic = clock(); pcl::PointCloud<int>::Ptr keypoint_idx(new pcl::PointCloud<int>); extract_keypoints( point_cloud, keypoints, keypoint_idx, keypoint_radius_ ); ROS_INFO("[vtree_user] Keypoint extraction took %f msec.", static_cast<double>((clock()-tic)*1000)/CLOCKS_PER_SEC ); if( keypoints->empty() ) { ROS_WARN("[vtree_user] No keypoints were found..."); return; } // Compute normals for the input cloud ROS_INFO("[vtree_user] Starting normal extraction..."); tic = clock(); pcl::PointCloud<pcl::Normal>::Ptr normals_(new pcl::PointCloud<pcl::Normal>); SearchMethod::Ptr search_method_xyz_ (new SearchMethod); pcl::NormalEstimation<PointT, pcl::Normal> norm_est; norm_est.setInputCloud ( point_cloud ); norm_est.setSearchMethod (search_method_xyz_); norm_est.setRadiusSearch (normal_radius_); norm_est.compute (*normals_); ROS_INFO("[vtree_user] Normal extraction took %f msec.", static_cast<double>((clock()-tic)*1000)/CLOCKS_PER_SEC ); // Get features at the computed keypoints ROS_INFO("[vtree_user] Starting feature computation..."); boost::shared_ptr<std::vector<int> > key_idx_ptr( new std::vector<int>); for( pcl::PointCloud<int>::iterator it = keypoint_idx->begin(); it != keypoint_idx->end(); ++it) key_idx_ptr->push_back( *it ); tic = clock(); FeatureEst feat_est; feat_est.setInputCloud ( point_cloud ); feat_est.setInputNormals (normals_); feat_est.setIndices( key_idx_ptr ); search_method_xyz_.reset(new SearchMethod); feat_est.setSearchMethod (search_method_xyz_); feat_est.setRadiusSearch (feature_radius_); feat_est.compute ( *features ); /* feat_est.setSearchSurface (point_cloud); feat_est.setInputNormals (normals_); feat_est.setInputCloud ( keypoints ); search_method_xyz_.reset(new SearchMethod); feat_est.setSearchMethod (search_method_xyz_); feat_est.setRadiusSearch (feature_radius_); feat_est.compute ( *features ); */ ROS_INFO("[vtree_user] Feature computation took %f msec.", static_cast<double>((clock()-tic)*1000)/CLOCKS_PER_SEC ); }