精华内容
下载资源
问答
  • 为准确识别三维物体,提出了一种新的物体特征框架,采用密集采样的多分辨率网格来描述物体观测图像的局部特征,引入Markov随机场模型对网格节点之间的几何关系进行建模。不同图像之间的匹配通过最高置信度优先算法...
  • 收集了一些三维物体识别算法相关的论文,比如“基于模型的三维物体识别”、“基于形态图表示的三维物体识别算法
  • 三维物体识别

    2013-06-17 10:04:01
    (Appearance-based)或基于视图(View-based)的三维物体识别算法研究,近来 成为人们研究的热点。基于视图的方法通过视觉相似性来识别物体,使得识别系 统设计相对简单,无需显式计算物体的三维模型。另外一方面,...
  • 三维目标识别算法综述

    千次阅读 2020-06-24 12:00:00
    点击上方“3D视觉工坊”,选择“星标”干货第一时间送达目前三维点云数据的获取方法相对快捷,同时三维点云数据的采集不受光照影响,也规避了二维图像遇到的光照、姿态等问题,因此基于点云数据的三...

    点击上方“3D视觉工坊”,选择“星标”

    干货第一时间送达

    目前三维点云数据的获取方法相对快捷,同时三维点云数据的采集不受光照影响,也规避了二维图像遇到的光照、姿态等问题,因此基于点云数据的三维物体识别也引起了人们的重视。

    三维点云物体识别方法多是通过提取物体的特征点几何属性、形状属性、结构属性或者多种属性的组合等特征进行比对、学习,从而完成物体的识别与分类。可以分为以下四类方法:

    1.基于局部特征的目标识别

    基于局部特征的物体识别方法主要是通过局部来识别整体。该方法无需对处理数据进行分割,往往通过提取物体的关键点、边缘或者面片等局部特征并进行比对来完成物体的识别。其中,特征提取是物体识别中非常关键的一步,它将直接影响到物体识别系统的性能。基于局部特征的方式对噪声和遮挡有更好的鲁棒性,同时不受颜色和纹理信息缺乏的限制。由于局部特征描述子仅使用参考点邻域信息,所以不对场景进行分割即可处理复杂场景。但是局部特征描述子维度较高,需要消耗更多的内存,同时存在计算复杂度高,实时性差等问题。

    点特征直方图(PFH)和快速点

    展开全文
  • PCL-基于对应分组的三维物体识别

    千次阅读 热门讨论 2019-11-24 22:37:00
    pcl 官网该教程 ... 对于表示场景中可能的模型实例的每个聚类,对应分组算法还输出识别当前场景中该模型的6DOF姿态估计的变换矩阵。 关于输入一个具体的物体的点云,从场景中找出与该物体点云相匹配的,这种...

    pcl 官网该教程
    本教程旨在解释如何基于pcl_recognition模块执行3D对象识别。 具体来说,它解释了如何使用对应分组算法,以便将在3D描述符匹配阶段之后获得的点对点对应集合聚类到当前场景中存在的模型实例中。 对于表示场景中可能的模型实例的每个聚类,对应分组算法还输出识别当前场景中该模型的6DOF姿态估计的变换矩阵

    关于输入一个具体的物体的点云,从场景中找出与该物体点云相匹配的,这种方法可以用来抓取指定的物体等等,代码说明:

    1. 对模型点云、场景点云分别进行下采样,得到稀疏关键点;

    2. 对模型点云、场景点云关键点,分别计算描述子;

    3. 利用KdTreeFLANN搜索对应点对;

    4. 使用【对应点聚类算法】将【对应点对】聚类为待识别模型;

    5. 返回识别到的每一个模型的变换矩阵(旋转矩阵+平移矩阵),以及对应点对聚类结果

    具体代码:

    #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/keypoints/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);
    bool use_hough_ (true);
    float model_ss_ (0.01f);
    float scene_ss_ (0.03f);
    float rf_rad_ (0.015f);
    float descr_rad_ (0.02f);
    float cg_size_ (0.01f);
    float cg_thresh_ (5.0f);
     
    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]];
      scene_filename_ = argv[filenames[1]];
     
      //Program behavior
      if (pcl::console::find_switch (argc, argv, "-k"))//可视化构造对应点时用到的关键点
      {
        show_keypoints_ = true;
      }
      if (pcl::console::find_switch (argc, argv, "-c"))//可视化支持实例假设的对应点对
      {
        show_correspondences_ = true;
      }
      if (pcl::console::find_switch (argc, argv, "-r"))//计算点云的分辨率和多样性
      {
        use_cloud_resolution_ = true;
      }
     
      std::string used_algorithm;
      if (pcl::console::parse_argument (argc, argv, "--algorithm", used_algorithm) != -1)
      {
        if (used_algorithm.compare ("Hough") == 0)
        {
          use_hough_ = true;
        }else if (used_algorithm.compare ("GC") == 0)
        {
          use_hough_ = false;
        }
        else
        {
          std::cout << "Wrong algorithm name.\n";
          showHelp (argv[0]);
          exit (-1);
        }
      }
     
      //General parameters
      pcl::console::parse_argument (argc, argv, "--model_ss", model_ss_);
      pcl::console::parse_argument (argc, argv, "--scene_ss", scene_ss_);
      pcl::console::parse_argument (argc, argv, "--rf_rad", rf_rad_);
      pcl::console::parse_argument (argc, argv, "--descr_rad", descr_rad_);
      pcl::console::parse_argument (argc, argv, "--cg_size", cg_size_);
      pcl::console::parse_argument (argc, argv, "--cg_thresh", cg_thresh_);
    }
     
    double
    computeCloudResolution (const pcl::PointCloud<PointType>::ConstPtr &cloud)
    {
      double res = 0.0;
      int n_points = 0;
      int nres;
      std::vector<int> indices (2);
      std::vector<float> sqr_distances (2);
      pcl::search::KdTree<PointType> tree;
      tree.setInputCloud (cloud);
     
      for (size_t i = 0; i < cloud->size (); ++i)
      {
        if (! pcl_isfinite ((*cloud)[i].x))
        {
          continue;
        }
        //Considering the second neighbor since the first is the point itself.
        nres = tree.nearestKSearch (i, 2, indices, sqr_distances);
        if (nres == 2)
        {
          res += sqrt (sqr_distances[1]);
          ++n_points;
        }
      }
      if (n_points != 0)
      {
        res /= n_points;
      }
      return res;
    }
     
    int
    main (int argc, char *argv[])
    {
      parseCommandLine (argc, argv);
     
      pcl::PointCloud<PointType>::Ptr model (new pcl::PointCloud<PointType> ());           //模型点云
      pcl::PointCloud<PointType>::Ptr model_keypoints (new pcl::PointCloud<PointType> ()); //模型角点
      pcl::PointCloud<PointType>::Ptr scene (new pcl::PointCloud<PointType> ());           //目标点云
      pcl::PointCloud<PointType>::Ptr scene_keypoints (new pcl::PointCloud<PointType> ()); //目标角点
      pcl::PointCloud<NormalType>::Ptr model_normals (new pcl::PointCloud<NormalType> ()); //法线
      pcl::PointCloud<NormalType>::Ptr scene_normals (new pcl::PointCloud<NormalType> ()); //
      pcl::PointCloud<DescriptorType>::Ptr model_descriptors (new pcl::PointCloud<DescriptorType> ()); //描述子
      pcl::PointCloud<DescriptorType>::Ptr scene_descriptors (new pcl::PointCloud<DescriptorType> ());
     
      //
      //  Load clouds
      //
      if (pcl::io::loadPCDFile (model_filename_, *model) < 0)
      {
        std::cout << "Error loading model cloud." << std::endl;
        showHelp (argv[0]);
        return (-1);
      }
      if (pcl::io::loadPCDFile (scene_filename_, *scene) < 0)
      {
        std::cout << "Error loading scene cloud." << std::endl;
        showHelp (argv[0]);
        return (-1);
      }
     
      //
      //  Set up resolution invariance
      //
      if (use_cloud_resolution_)
      {
        float resolution = static_cast<float> (computeCloudResolution (model));
        if (resolution != 0.0f)
        {
          model_ss_   *= resolution;
          scene_ss_   *= resolution;
          rf_rad_     *= resolution;
          descr_rad_  *= resolution;
          cg_size_    *= resolution;
        }
     
        std::cout << "Model resolution:       " << resolution << std::endl;
        std::cout << "Model sampling size:    " << model_ss_ << std::endl;
        std::cout << "Scene sampling size:    " << scene_ss_ << std::endl;
        std::cout << "LRF support radius:     " << rf_rad_ << std::endl;
        std::cout << "SHOT descriptor radius: " << descr_rad_ << std::endl;
        std::cout << "Clustering bin size:    " << cg_size_ << std::endl << std::endl;
      }
     
      //
      //  Compute Normals:计算法线
      //
      pcl::NormalEstimationOMP<PointType, NormalType> norm_est;
      norm_est.setNumberOfThreads(4);   //手动设置线程数
      norm_est.setKSearch (10);         //设置k邻域搜索阈值为10个点
      norm_est.setInputCloud (model);   //设置输入模型点云
      norm_est.compute (*model_normals);//计算点云法线
     
      norm_est.setInputCloud (scene);
      norm_est.compute (*scene_normals);
     
      //
      // Downsample Clouds to Extract keypoints:均匀采样点云并提取关键点
      // 类UniformSampling实现对点云的统一重采样,具体通过建立点云的空间体素栅格,然后在此基础上实现下采样并且过滤一些数据。
      // 所有采样后得到的点用每个体素内点集的重心近似,而不是用每个体素的中心点近似,前者速度较后者慢,但其估计的点更接近实际的采样面。
      //
     
      //pcl::PointCloud<int> sampled_indices;
      pcl::UniformSampling<PointType> uniform_sampling;
      uniform_sampling.setInputCloud (model);        //输入点云
      uniform_sampling.setRadiusSearch (model_ss_);  //输入半径
      //uniform_sampling.compute (sampled_indices);
      //pcl::copyPointCloud (*model, sampled_indices.points, *model_keypoints);
      uniform_sampling.filter(*model_keypoints);   //滤波
     
      std::cout << "Model total points: " << model->size () << "; Selected Keypoints: " << model_keypoints->size () << std::endl;
     
      uniform_sampling.setInputCloud (scene);
      uniform_sampling.setRadiusSearch (scene_ss_);
      //uniform_sampling.compute (sampled_indices);
      //pcl::copyPointCloud (*scene, sampled_indices.points, *scene_keypoints);
      uniform_sampling.filter(*scene_keypoints);
      std::cout << "Scene total points: " << scene->size () << "; Selected Keypoints: " << scene_keypoints->size () << std::endl;
     
      //
      //  Compute Descriptor for keypoints:为关键点计算描述子
      //
      pcl::SHOTEstimationOMP<PointType, NormalType, DescriptorType> descr_est;
      descr_est.setNumberOfThreads(4);
      descr_est.setRadiusSearch (descr_rad_);     //设置搜索半径
     
      descr_est.setInputCloud (model_keypoints);  //模型点云的关键点
      descr_est.setInputNormals (model_normals);  //模型点云的法线 
      descr_est.setSearchSurface (model);         //模型点云       
      descr_est.compute (*model_descriptors);     //计算描述子
     
      descr_est.setInputCloud (scene_keypoints);
      descr_est.setInputNormals (scene_normals);
      descr_est.setSearchSurface (scene);
      descr_est.compute (*scene_descriptors);
     
      //
      //  Find Model-Scene Correspondences with KdTree:使用Kdtree找出 Model-Scene 匹配点
      //
      pcl::CorrespondencesPtr model_scene_corrs (new pcl::Correspondences ());
     
      pcl::KdTreeFLANN<DescriptorType> match_search; //设置配准方式
      match_search.setInputCloud (model_descriptors);//模型点云的描述子
     
     
      //每一个场景的关键点描述子都要找到模板中匹配的关键点描述子并将其添加到对应的匹配向量中。
      for (size_t i = 0; i < scene_descriptors->size (); ++i)
      {
        std::vector<int> neigh_indices (1);    //设置最近邻点的索引
        std::vector<float> neigh_sqr_dists (1);//设置最近邻平方距离值
        if (!pcl_isfinite (scene_descriptors->at (i).descriptor[0])) //忽略 NaNs点
        {
          continue;
        }
        int found_neighs = match_search.nearestKSearch (scene_descriptors->at (i), 1, neigh_indices, neigh_sqr_dists);
        if(found_neighs == 1 && neigh_sqr_dists[0] < 0.25f) //仅当描述子与临近点的平方距离小于0.25(描述子与临近的距离在一般在0到1之间)才添加匹配
        {
    		//neigh_indices[0]给定点,i是配准数neigh_sqr_dists[0]与临近点的平方距离
          pcl::Correspondence corr (neigh_indices[0], static_cast<int> (i), neigh_sqr_dists[0]);
          model_scene_corrs->push_back (corr);//把配准的点存储在容器中
        }
      }
      std::cout << "Correspondences found: " << model_scene_corrs->size () << std::endl;
     
      //
      //  Actual Clustering:实际的配准方法的实现
      //
      std::vector<Eigen::Matrix4f, Eigen::aligned_allocator<Eigen::Matrix4f> > rototranslations;
      std::vector<pcl::Correspondences> clustered_corrs;
     
      // 使用 Hough3D算法寻找匹配点
      if (use_hough_)
      {
        //
        //  Compute (Keypoints) Reference Frames only for Hough
        //
    	//利用hough算法时,需要计算关键点的局部参考坐标系(LRF)
        pcl::PointCloud<RFType>::Ptr model_rf (new pcl::PointCloud<RFType> ());
        pcl::PointCloud<RFType>::Ptr scene_rf (new pcl::PointCloud<RFType> ());
    	
        pcl::BOARDLocalReferenceFrameEstimation<PointType, NormalType, RFType> rf_est;
        rf_est.setFindHoles (true);
        rf_est.setRadiusSearch (rf_rad_);//估计局部参考坐标系时当前点的邻域搜索半径
     
        rf_est.setInputCloud (model_keypoints);
        rf_est.setInputNormals (model_normals);
        rf_est.setSearchSurface (model);
        rf_est.compute (*model_rf);
     
        rf_est.setInputCloud (scene_keypoints);
        rf_est.setInputNormals (scene_normals);
        rf_est.setSearchSurface (scene);
        rf_est.compute (*scene_rf);
     
        //  Clustering
        pcl::Hough3DGrouping<PointType, PointType, RFType, RFType> clusterer;
        clusterer.setHoughBinSize (cg_size_);     //hough空间的采样间隔:0.01
        clusterer.setHoughThreshold (cg_thresh_); //在hough空间确定是否有实例存在的最少票数阈值:5
        clusterer.setUseInterpolation (true);     //设置是否对投票在hough空间进行插值计算
        clusterer.setUseDistanceWeight (false);   //设置在投票时是否将对应点之间的距离作为权重参与计算
     
        clusterer.setInputCloud (model_keypoints); //设置模型点云的关键点
        clusterer.setInputRf (model_rf);           //设置模型对应的局部坐标系
        clusterer.setSceneCloud (scene_keypoints);
        clusterer.setSceneRf (scene_rf);
        clusterer.setModelSceneCorrespondences (model_scene_corrs);//设置模型与场景的对应点的集合
     
        //clusterer.cluster (clustered_corrs);
        clusterer.recognize (rototranslations, clustered_corrs); //结果包含变换矩阵和对应点聚类结果
      }
      else // Using GeometricConsistency:使用几何一致性性质
      {
        pcl::GeometricConsistencyGrouping<PointType, PointType> gc_clusterer;
        gc_clusterer.setGCSize (cg_size_);        //设置几何一致性的大小
        gc_clusterer.setGCThreshold (cg_thresh_); //阈值
     
        gc_clusterer.setInputCloud (model_keypoints);
        gc_clusterer.setSceneCloud (scene_keypoints);
        gc_clusterer.setModelSceneCorrespondences (model_scene_corrs);
     
        //gc_clusterer.cluster (clustered_corrs);
        gc_clusterer.recognize (rototranslations, clustered_corrs);
      }
     
      //
      //  Output results:找出输入模型是否在场景中出现
      //
      std::cout << "Model instances found: " << rototranslations.size () << std::endl;
      for (size_t i = 0; i < rototranslations.size (); ++i)
      {
        std::cout << "\n    Instance " << i + 1 << ":" << std::endl;
        std::cout << "        Correspondences belonging to this instance: " << clustered_corrs[i].size () << std::endl;
     
        //打印处相对于输入模型的旋转矩阵与平移矩阵
        Eigen::Matrix3f rotation = rototranslations[i].block<3,3>(0, 0);
        Eigen::Vector3f translation = rototranslations[i].block<3,1>(0, 3);
     
        printf ("\n");
        printf ("            | %6.3f %6.3f %6.3f | \n", rotation (0,0), rotation (0,1), rotation (0,2));
        printf ("        R = | %6.3f %6.3f %6.3f | \n", rotation (1,0), rotation (1,1), rotation (1,2));
        printf ("            | %6.3f %6.3f %6.3f | \n", rotation (2,0), rotation (2,1), rotation (2,2));
        printf ("\n");
        printf ("        t = < %0.3f, %0.3f, %0.3f >\n", translation (0), translation (1), translation (2));
      }
     
      //
      //  Visualization
      //
      pcl::visualization::PCLVisualizer viewer ("点云库PCL学习教程第二版-基于对应点聚类的3D模型识别");
      viewer.addPointCloud (scene, "scene_cloud");//可视化场景点云
      viewer.setBackgroundColor(255,255,255);
      pcl::PointCloud<PointType>::Ptr off_scene_model (new pcl::PointCloud<PointType> ());
      pcl::PointCloud<PointType>::Ptr off_scene_model_keypoints (new pcl::PointCloud<PointType> ());
     
      if (show_correspondences_ || show_keypoints_)//可视化配准点
      {
        //We are translating the model so that it doesn't end in the middle of the scene representation
    	//对输入的模型进行旋转与平移,使其在可视化界面的中间位置
        pcl::transformPointCloud (*model, *off_scene_model, Eigen::Vector3f (0,0,0), Eigen::Quaternionf (1, 0, 0, 0));
        pcl::transformPointCloud (*model_keypoints, *off_scene_model_keypoints, Eigen::Vector3f (-1,0,0), Eigen::Quaternionf (1, 0, 0, 0));
     
        pcl::visualization::PointCloudColorHandlerCustom<PointType> off_scene_model_color_handler (off_scene_model, 0, 255, 0);
        viewer.addPointCloud (off_scene_model, off_scene_model_color_handler, "off_scene_model");
      }
     
      if (show_keypoints_)//可视化关键点:蓝色
      {
        pcl::visualization::PointCloudColorHandlerCustom<PointType> scene_keypoints_color_handler (scene_keypoints, 0, 0, 255);
        viewer.addPointCloud (scene_keypoints, scene_keypoints_color_handler, "scene_keypoints");
        viewer.setPointCloudRenderingProperties (pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 5, "scene_keypoints");
     
        pcl::visualization::PointCloudColorHandlerCustom<PointType> off_scene_model_keypoints_color_handler (off_scene_model_keypoints, 0, 0, 255);
        viewer.addPointCloud (off_scene_model_keypoints, off_scene_model_keypoints_color_handler, "off_scene_model_keypoints");
        viewer.setPointCloudRenderingProperties (pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 5, "off_scene_model_keypoints");
      }
     
      for (size_t i = 0; i < rototranslations.size (); ++i)
      {
        pcl::PointCloud<PointType>::Ptr rotated_model (new pcl::PointCloud<PointType> ());
        pcl::transformPointCloud (*model, *rotated_model, rototranslations[i]);//把model转化为rotated_model
     
        std::stringstream ss_cloud;
        ss_cloud << "instance" << i;
     
        pcl::visualization::PointCloudColorHandlerCustom<PointType> rotated_model_color_handler (rotated_model, 255, 0, 0);
        viewer.addPointCloud (rotated_model, rotated_model_color_handler, ss_cloud.str ());
     
        if (show_correspondences_)//显示配准连接线
        {
          for (size_t j = 0; j < clustered_corrs[i].size (); ++j)
          {
            std::stringstream ss_line;
            ss_line << "correspondence_line" << i << "_" << j;
            PointType& model_point = off_scene_model_keypoints->at (clustered_corrs[i][j].index_query);
            PointType& scene_point = scene_keypoints->at (clustered_corrs[i][j].index_match);
     
            //  We are drawing a line for each pair of clustered correspondences found between the model and the scene
            viewer.addLine<PointType, PointType> (model_point, scene_point, 0, 255, 0, ss_line.str ());
          }
        }
      }
     
      while (!viewer.wasStopped ())
      {
        viewer.spinOnce ();
      }
     
      return (0);
    }
    

    如果用书中带的pcd,加载milk_pose_changed.pcd时,会报“Failed to find match for field ‘rgba’.”因为这个文件中不包括rgba信息;可从官网下载原始文件:源文件github地址

    命令行输入指令说明:

      -k:                在源点云和场景点云中    显示关键点 
      -c:                显示对应点连线
    

    ./correspondence_grouping milk.pcd milk_cartoon_all_small_clorox.pcd -c
    效果显示如下
    结果显示
    ./correspondence_grouping milk.pcd milk_cartoon_all_small_clorox.pcd -c -k效果显示如下
    在这里插入图片描述

    控制台输出结果
    结果显示:关键点(蓝色),识别出的模型实例(红色),对应点对连接线(绿色) 源点云(黄色)

    重点:为什么R和T的值都是原始值:因为 源点云和目标点云完全重合

    我们将源点云进行旋转平移后再匹配,结果如下
    在这里插入图片描述
    [pcl::SHOTEstimation::computeFeature] The local reference frame is not valid! Aborting description of point with index 3045

    这个错误是由于正常半径较小的事实,一些法线是NaN(在设置半径的球体内它们的邻域中没有点),导致SHOT出现问题。

    只需要把代码中的,在这里插入图片描述搜索半径改大点。

    之后我尝试将源点云与多个相同点云进行 匹配,结果如下

    在这里插入图片描述
    在这里插入图片描述
    但是我用自己的数据集并没有实现点云匹配 正在修改参数中 ,哪位可以指点一下,谢谢

    展开全文
  • 基于LineMod与ORK的三维物体识别与姿态估计

    基于LineMod与ORK的三维物体识别与姿态估计

    下图是OpenCV linemod,感觉有点不太准。

    ORK识别,感觉环境配置有点难。识别桌面然后提取平面内的物体。不建议使用,这个链接里的PDF有详细使用感受,要是早看到就好了:https://ipvs.informatik.uni-stuttgart.de/mlr/papers/15-kaelberer_klein_paule-Fachstudie.pdf 

    展开全文
  • 一篇很好的物体识别方面的文献,主要讲的是sift算法
  • 种强大的物体识别算法

    万次阅读 2015-08-13 22:52:48
    三种强大的物体识别算法 —— SIFT/SURF 、 haar 特征、广义 hough 变换 的特性对比分析   收藏   识别算法概述:       SIFT/SURF 基于灰度图,   一、首先建立图像金字塔,形成三维的图像...

    SIFT/SURF基于灰度图,

    一、首先建立图像金字塔,形成三维的图像空间,通过Hessian矩阵获取每一层的局部极大值,然后进行在极值点周围26个点进行NMS,从而得到粗略的特征点,再使用二次插值法得到精确特征点所在的层(尺度),即完成了尺度不变。

    二、在特征点选取一个与尺度相应的邻域,求出主方向,其中SIFT采用在一个正方形邻域内统计所有点的梯度方向,找到占80%以上的方向作为主方向;而SURF则选择圆形邻域,并且使用活动扇形的方法求出特征点主方向,以主方向对齐即完成旋转不变。

    三、以主方向为轴可以在每个特征点建立坐标,SIFT在特征点选择一块大小与尺度相应的方形区域,分成16块,统计每一块沿着八个方向占的比例,于是特征点形成了128维特征向量,对图像进行归一化则完成强度不变;而SURF分成64块,统计每一块的dx,dy,|dx|,|dy|的累积和,同样形成128维向量,再进行归一化则完成了对比度不变与强度不变。

     

    haar特征也是基于灰度图,

    首先通过大量的具有比较明显的haar特征(矩形)的物体图像用模式识别的方法训练出分类器,分类器是个级联的,每级都以大概相同的识别率保留进入下一级的具有物体特征的候选物体,而每一级的子分类器则由许多haar特征构成(由积分图像计算得到,并保存下位置),有水平的、竖直的、倾斜的,并且每个特征带一个阈值和两个分支值,每级子分类器带一个总的阈值。识别物体的时候,同样计算积分图像为后面计算haar特征做准备,然后采用与训练的时候有物体的窗口同样大小的窗口遍历整幅图像,以后逐渐放大窗口,同样做遍历搜索物体;每当窗口移动到一个位置,即计算该窗口内的haar特征,加权后与分类器中haar特征的阈值比较从而选择左或者右分支值,累加一个级的分支值与相应级的阈值比较,大于该阈值才可以通过进入下一轮筛选。当通过分类器所以级的时候说明这个物体以大概率被识别。

     

    广义hough变换同样基于灰度图,

    使用轮廓作为特征,融合了梯度信息,以投票的方式识别物体,在本blog的另一篇文章中有详细讨论,这里不再赘述。

     

     

    特点异同对比及其适用场合:

     

    三种算法都只是基于强度(灰度)信息,都是特征方法,但SIFT/SURF的特征是一种具有强烈方向性及亮度性的特征,这使得它适用于刚性形变,稍有透视形变的场合;haar特征识别方法带有一点人工智能的意味,对于像人脸这种有明显的、稳定结构的haar特征的物体最适用,只要结构相对固定即使发生扭曲等非线性形变依然可识别;广义hough变换完全是精确的匹配,可得到物体的位置方向等参数信息。前两种方法基本都是通过先获取局部特征然后再逐个匹配,只是局部特征的计算方法不同,SIFT/SURF比较复杂也相对稳定,haar方法比较简单,偏向一种统计的方法形成特征,这也使其具有一定的模糊弹性;广义hough变换则是一种全局的特征——轮廓梯度,但也可以看做整个轮廓的每一个点的位置和梯度都是特征,每个点都对识别有贡献,用直观的投票,看票数多少去确定是否识别出物体。

    转自:http://blog.csdn.net/cy513/article/details/4285579
    展开全文
  • 视觉抓取中非常重要的一个部分就是对抓取物体的识别,无论是二维图像还是三维...object_2d包进行了简单的测试,本次测试的是三维物体识别的框架,该框架是基于物体的三维模型进行训练并识别,大致的思想也是模板...
  • 针对目前高机动目标跟踪的Jerk模型存在计算复杂度高和α-β-γ模型须预先估计过程噪声标准偏差的不足,提出了一种基于Jerk模型的常增益滤波算法:自适应的α-β-γ-δ模型,并从理论上推导出了上述新模型中α、β、...
  • 人类是如何识别一个物体的呢,当然要对面前的这个物体为何物要有一个概念,人类一生下来就开始通过视觉获取世间万物的信息,包括一种物体形状、颜色、成分等,以及通过学习认识到这种物体的其他信息比如物理的、化学...
  • 一文教会你三维网格物体识别

    千次阅读 2018-06-15 18:13:18
    本文由「图普科技」编译自Medium2017年3月,当时我的老板说自动识别3D物体几乎是不可能的,但大家一致反对。因此,今天我要解决的问题是:如何输入3D网格物体(原始三角形和顶点),得到分类概率的输出。我找到了...
  • 铁路场景三维点云分割与分类识别算法.pdf,铁路限界侵入检测对保障高速铁路安全具有重要意义,基于激光三维点云分割与分类识别的异物侵入检测具有准确、直观的优点,在诸如隧道口和站台的铁路重点区域监测中具有广泛...
  • 三种强大的物体识别算法——SIFT/SURF、haar特征、广义hough变换的特性对比分析 识别算法概述:    SIFT/SURF基于灰度图, 一、首先建立图像金字塔,形成三维的图像空间,通过Hessian矩阵获取每一层的局部极大...
  • 三维人脸识别研究

    千次阅读 2019-11-05 09:42:19
    虽然基于二维图像的人脸识别算法在半个多世纪的研究过程中,取得了丰硕的成果,但是研究表明,基于二维图像分析的人脸识别方法受到诸如光照、姿态、表情等成像条件的影响较大。与二维数据相比,三维数据包含了人脸的...
  • 利用级联神经网络模型对多个三维目标进行识别,为提高其正确识别率,提出多种优化方法,它们可单独使用,也可以联合使用。对不变性编码、算法、互连权重的二值化方法、样本优选等进行了研究和探讨。利用优化后的模型对三...
  • 近二十多年来,虽然基于图像的人脸识别已取得很大进展,并可在约束环境下获得很好的识别性能,但仍受光照、姿态、表情等变化的影响很大,其本质原因在于图像是三维物体在二维空间的简约投影.因此,利用脸部曲面的显式三维...
  • 基于深度学习的三维点云识别

    万次阅读 多人点赞 2018-10-10 10:23:34
    一、什么是三维物体识别 ​ 随着三维成像技术的发展,结构光测量、激光扫描、ToF等技术趋于成熟,物体表面的三维坐标能够精准而快速的获取,从而生成场景的三维数据,能够更好地感知和理解周围环境。三维数据包含了...
  • 针对该问题, 提出了一种新的基于路径轮廓的三维目标识别算法。该算法首先定义了一种新的特征点——骨切点, 并根据骨切点在轮廓曲线上的顺序关系, 对骨架端点进行排序; 然后利用路径轮廓对目标轮廓进行分割; 再构造一...
  • 一、首先建立图像金字塔,形成三维的图像空间,通过Hessian矩阵获取每一层的局部极大值,然后进行在极值点周围26个点进行NMS,从而得到粗略的特征点,再使用二次插值法得到精确特征点所在的层(尺度),即完成了尺度...
  • david lowe的三维识别算法,模块化程序实例讲解sift三维物体识别

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 24,393
精华内容 9,757
关键字:

三维物体识别算法