点云技术相关产学研社区

 找回密码
 立即注册加入PCL中国点云技术相关产学研社区

扫一扫,访问微社区

查看: 4457|回复: 1

【求助】特征匹配耗时长结果差如何解决(附代码)

[复制链接]
发表于 2017-4-16 05:46:42 | 显示全部楼层 |阅读模式
最近在帮老师做项目要用PCL进行特征匹配识别在一个场景下找对应物体的模型。我的代码总是需要跑很长时间并且结果很差
求大神帮忙看看要调整那些步骤或参数才能得到一个比较好的结果。

附件中有结果图片和代码。在此先谢谢看这篇帖子的人了。

代码如下:

#include <pcl/features/ppf.h>
#include <pcl/io/pcd_io.h>
#include <pcl/filters/voxel_grid.h>
#include <pcl/features/normal_3d.h>
#include <pcl/registration/ppf_registration.h>

#include <pcl/visualization/pcl_visualizer.h>
#include <pcl/segmentation/sac_segmentation.h>
#include <pcl/filters/extract_indices.h>
#include <pcl/sample_consensus/method_types.h>
#include <pcl/sample_consensus/model_types.h>


using namespace pcl;
using namespace std;



const Eigen::Vector4f subsampling_leaf_size(0.02f, 0.02f, 0.02f, 0.0f);//0.02
const float normal_estimation_search_radius = 0.05f;//0.05



string model_file = "D:/FeatureMatching/data/4x8sTracking.pcd";
string scene_file = "D:/FeatureMatching/data/Legotest.pcd";



PointCloud<PointNormal>::Ptr
subsampleAndCalculateNormals(PointCloud<PointXYZ>::Ptr cloud, Eigen::Vector4f a)

{

        PointCloud<PointXYZ>::Ptr cloud_subsampled(new PointCloud<PointXYZ>());

        VoxelGrid<PointXYZ> subsampling_filter;

        subsampling_filter.setInputCloud(cloud);

        subsampling_filter.setLeafSize(a);

        subsampling_filter.filter(*cloud_subsampled);



        PointCloud<Normal>::Ptr cloud_subsampled_normals(new PointCloud<Normal>());

        NormalEstimation<PointXYZ, Normal> normal_estimation_filter;

        normal_estimation_filter.setInputCloud(cloud_subsampled);

        search::KdTree<PointXYZ>::Ptr search_tree(new search::KdTree<PointXYZ>);

        normal_estimation_filter.setSearchMethod(search_tree);

        normal_estimation_filter.setRadiusSearch(normal_estimation_search_radius);

        normal_estimation_filter.compute(*cloud_subsampled_normals);



        PointCloud<PointNormal>::Ptr cloud_subsampled_with_normals(new PointCloud<PointNormal>());

        concatenateFields(*cloud_subsampled, *cloud_subsampled_normals, *cloud_subsampled_with_normals);



        PCL_INFO("Cloud dimensions before / after subsampling: %u / %u\n", cloud->points.size(), cloud_subsampled->points.size());

        return cloud_subsampled_with_normals;

}



int main(int argc, char** argv)

{





        /// read point clouds from HDD

        PCL_INFO("Reading scene ...\n");
        PointCloud<PointXYZ>::Ptr cloud_scene(new PointCloud<PointXYZ>());
        PCDReader reader;
        reader.read(scene_file, *cloud_scene);

        PCL_INFO("Scene read: %s\n", scene_file);
        PCL_INFO("Reading models ...\n");

        vector<PointCloud<PointXYZ>::Ptr > cloud_models;



        PointCloud<PointXYZ>::Ptr cloud(new PointCloud<PointXYZ>());
        reader.read(model_file, *cloud);
        cloud_models.push_back(cloud);
        PCL_INFO("Model read: %s\n", model_file);




        pcl::SACSegmentation<pcl::PointXYZ> seg;
        pcl::ExtractIndices<pcl::PointXYZ> extract;

        seg.setOptimizeCoefficients(true);
        seg.setModelType(pcl::SACMODEL_PLANE);
        seg.setMethodType(pcl::SAC_RANSAC);
        seg.setMaxIterations(1000);
        seg.setDistanceThreshold(0.05);//0.05
        extract.setNegative(true);

        pcl::ModelCoefficients::Ptr coefficients(new pcl::ModelCoefficients());
        pcl::PointIndices::Ptr inliers(new pcl::PointIndices());

        unsigned nr_points = unsigned(cloud_scene->points.size());
        while (cloud_scene->points.size() > 0.2 * nr_points)////////////////////////////////////////////////0.2
        {

                seg.setInputCloud(cloud_scene);
                seg.segment(*inliers, *coefficients);
                PCL_INFO("Plane inliers: %u\n", inliers->indices.size());

                if (inliers->indices.size() < 50000) break;//50000
                extract.setInputCloud(cloud_scene);
                extract.setIndices(inliers);
                extract.filter(*cloud_scene);

        }


        Eigen::Vector4f subsampling_leaf_size_scene(0.02f, 0.02f, 0.02f, 0.0f);
        Eigen::Vector4f subsampling_leaf_size_model(0.01f, 0.01f, 0.01f, 0.0f);
        PointCloud<PointNormal>::Ptr cloud_scene_input = subsampleAndCalculateNormals(cloud_scene, subsampling_leaf_size_scene);
        vector<PointCloud<PointNormal>::Ptr > cloud_models_with_normals;
        PCL_INFO("Training models ...\n");

        vector<PPFHashMapSearch::Ptr> hashmap_search_vector;
        for (size_t model_i = 0; model_i < cloud_models.size(); ++model_i)
        {

                PointCloud<PointNormal>::Ptr cloud_model_input = subsampleAndCalculateNormals(cloud_models[model_i], subsampling_leaf_size_model);
                cloud_models_with_normals.push_back(cloud_model_input);


                PointCloud<PPFSignature>::Ptr cloud_model_ppf(new PointCloud<PPFSignature>());
                PPFEstimation<PointNormal, PointNormal, PPFSignature> ppf_estimator;
                ppf_estimator.setInputCloud(cloud_model_input);
                ppf_estimator.setInputNormals(cloud_model_input);
                ppf_estimator.compute(*cloud_model_ppf);



                PPFHashMapSearch::Ptr hashmap_search(new PPFHashMapSearch(12.0f / 180.0f * float(M_PI),0.2f));///////////////////////////////////////12.0,0.5

                hashmap_search->setInputFeatureCloud(cloud_model_ppf);
                hashmap_search_vector.push_back(hashmap_search);

        }





        visualization::PCLVisualizer viewer("PPF Object Recognition - Results");
        viewer.setBackgroundColor(0, 0, 0);
        viewer.addPointCloud(cloud_scene);
        viewer.spinOnce(10);
        PCL_INFO("Registering models to scene ...\n");
        for (size_t model_i = 0; model_i < cloud_models.size(); ++model_i)
        {
                //PCL_INFO("%u\n", model_i);


                PPFRegistration<PointNormal, PointNormal> ppf_registration;

                // set parameters for the PPF registration procedure

                ppf_registration.setSceneReferencePointSamplingRate(10);/////////////
                ppf_registration.setPositionClusteringThreshold(0.20f);//////////////////
                ppf_registration.setRotationClusteringThreshold(12.0f / 180.0f * float(M_PI));///////////////
                ppf_registration.setSearchMethod(hashmap_search_vector[model_i]);
                ppf_registration.setInputSource(cloud_models_with_normals[model_i]);
                ppf_registration.setInputTarget(cloud_scene_input);



                PointCloud<PointNormal> cloud_output_subsampled;
                ppf_registration.align(cloud_output_subsampled);

                PointCloud<PointXYZ>::Ptr cloud_output_subsampled_xyz(new PointCloud<PointXYZ>());

                for (size_t i = 0; i < cloud_output_subsampled.points.size(); ++i)
                        cloud_output_subsampled_xyz->points.push_back(PointXYZ(cloud_output_subsampled.points.x, cloud_output_subsampled.points.y, cloud_output_subsampled.points.z));


                Eigen::Matrix4f mat = ppf_registration.getFinalTransformation();
                Eigen::Affine3f final_transformation(mat);

                //  io::savePCDFileASCII ("output_subsampled_registered.pcd", cloud_output_subsampled);
                PointCloud<PointXYZ>::Ptr cloud_output(new PointCloud<PointXYZ>());
                pcl::transformPointCloud(*cloud_models[model_i], *cloud_output, final_transformation);


                stringstream ss; ss << "model_" << model_i;
                visualization::PointCloudColorHandlerRandom<PointXYZ> random_color(cloud_output->makeShared());
                viewer.addPointCloud(cloud_output, random_color, ss.str());

                //    io::savePCDFileASCII (ss.str ().c_str (), *cloud_output);
                PCL_INFO("Showing model %s\n", ss.str().c_str());

        }



        PCL_INFO("All models have been registered!\n");





        while (!viewer.wasStopped())
        {

                viewer.spinOnce(100);

                boost::this_thread::sleep(boost::posix_time::microseconds(100000));

        }



        return 0;

}
\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\



本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?立即注册加入PCL中国点云技术相关产学研社区

x
回复

使用道具 举报

发表于 2017-12-5 11:37:09 | 显示全部楼层
不知有没有考虑过使用GPU做?
回复 支持 反对

使用道具 举报

本版积分规则

QQ|小黑屋|点云技术相关产学研社区 ( 陕ICP备13001629号 )

GMT+8, 2024-4-26 04:51 , Processed in 1.833754 second(s), 17 queries .

Powered by Discuz! X3.4

© 2001-2017 Comsenz Inc.

快速回复 返回顶部 返回列表