71551


PointCloudLibrary(PCL)を用いて円柱検出を行なっていました。円柱検出を行うプログラムは以下の通りです(ほとんどPCLチュートリアルのままです)。

[code]

    #include <pcl/ModelCoefficients.h>
    #include <pcl/io/pcd_io.h>
    #include <pcl/point_types.h>
    #include <pcl/filters/extract_indices.h>
    #include <pcl/filters/passthrough.h>
    #include <pcl/features/normal_3d.h>
    #include <pcl/sample_consensus/method_types.h>
    #include <pcl/sample_consensus/model_types.h>
    #include <pcl/segmentation/sac_segmentation.h>
    
    typedef pcl::PointXYZ PointT;
    
    int
    main (int argc, char** argv)
    {
      std::string filename = "inputfile.pcd";
    
      // All the objects needed
      pcl::PCDReader reader;
      pcl::PassThrough<PointT> pass;
      pcl::NormalEstimation<PointT, pcl::Normal> ne;
      pcl::SACSegmentationFromNormals<PointT, pcl::Normal> seg; 
      pcl::PCDWriter writer;
      pcl::ExtractIndices<PointT> extract;
      pcl::ExtractIndices<pcl::Normal> extract_normals;
      pcl::search::KdTree<PointT>::Ptr tree (new pcl::search::KdTree<PointT> ());
    
      // Datasets
      pcl::PointCloud<PointT>::Ptr cloud (new pcl::PointCloud<PointT>);
      pcl::PointCloud<PointT>::Ptr cloud_filtered (new pcl::PointCloud<PointT>);
      pcl::PointCloud<pcl::Normal>::Ptr cloud_normals (new pcl::PointCloud<pcl::Normal>);
      pcl::PointCloud<PointT>::Ptr cloud_filtered2 (new pcl::PointCloud<PointT>);
      pcl::PointCloud<pcl::Normal>::Ptr cloud_normals2 (new pcl::PointCloud<pcl::Normal>);
      pcl::ModelCoefficients::Ptr coefficients_plane (new pcl::ModelCoefficients), 
    coefficients_cylinder (new pcl::ModelCoefficients);
      pcl::PointIndices::Ptr inliers_plane (new pcl::PointIndices), inliers_cylinder (new 
    pcl::PointIndices);
    
      // Read in the cloud data
      reader.read (filename, *cloud);
      std::cerr << "PointCloud has: " << cloud->points.size () << " data points." << std::endl;
    
      // Build a passthrough filter to remove spurious NaNs
      pass.setInputCloud (cloud);
      pass.setFilterFieldName ("z");
      pass.setFilterLimits (0, 1.5);
      pass.filter (*cloud_filtered);
      std::cerr << "PointCloud after filtering has: " << cloud_filtered->points.size () << " 
    data points." << std::endl;
    
      // Estimate point normals
      ne.setSearchMethod (tree);
      ne.setInputCloud (cloud_filtered);
      ne.setKSearch (50);
      ne.compute (*cloud_normals);
    
      // Create the segmentation object for the planar model and set all the parameters
      seg.setOptimizeCoefficients (true);
      seg.setModelType (pcl::SACMODEL_NORMAL_PLANE);
      seg.setNormalDistanceWeight (0.1);
      seg.setMethodType (pcl::SAC_RANSAC);
      seg.setMaxIterations (100);
      seg.setDistanceThreshold (0.03);
      seg.setInputCloud (cloud_filtered);
      seg.setInputNormals (cloud_normals);
      // Obtain the plane inliers and coefficients
      seg.segment (*inliers_plane, *coefficients_plane);
      std::cerr << "Plane coefficients: " << *coefficients_plane << std::endl;
    
      // Extract the planar inliers from the input cloud
      extract.setInputCloud (cloud_filtered);
      extract.setIndices (inliers_plane);
      extract.setNegative (false);
    
      // Write the planar inliers to disk
      pcl::PointCloud<PointT>::Ptr cloud_plane (new pcl::PointCloud<PointT> ());
      extract.filter (*cloud_plane);
      std::cerr << "PointCloud representing the planar component: " << cloud_plane->points.size 
    () << " data points." << std::endl;
      writer.write (filename, *cloud_plane, false);
    
      // Remove the planar inliers, extract the rest
      extract.setNegative (true);
      extract.filter (*cloud_filtered2);
      extract_normals.setNegative (true);
      extract_normals.setInputCloud (cloud_normals);
      extract_normals.setIndices (inliers_plane);
      extract_normals.filter (*cloud_normals2);
    
      // Create the segmentation object for cylinder segmentation and set all the parameters
      seg.setOptimizeCoefficients (true);
      seg.setModelType (pcl::SACMODEL_CYLINDER);
      seg.setMethodType (pcl::SAC_RANSAC);
      seg.setNormalDistanceWeight (0.1);
      seg.setMaxIterations (10000);
      seg.setDistanceThreshold (0.05);
      seg.setRadiusLimits (0, 0.1);
      seg.setInputCloud (cloud_filtered2);
      seg.setInputNormals (cloud_normals2);
    
      // Obtain the cylinder inliers and coefficients
      seg.segment (*inliers_cylinder, *coefficients_cylinder);
      std::cerr << "Cylinder coefficients: " << *coefficients_cylinder << std::endl;
    
      // Write the cylinder inliers to disk
      extract.setInputCloud (cloud_filtered2);
      extract.setIndices (inliers_cylinder);
      extract.setNegative (false);
      pcl::PointCloud<PointT>::Ptr cloud_cylinder (new pcl::PointCloud<PointT> ());
      extract.filter (*cloud_cylinder);
      if (cloud_cylinder->points.empty ()) 
        std::cerr << "Can't find the cylindrical component." << std::endl;
      else
      {
          std::cerr << "PointCloud representing the cylindrical component: " << cloud_cylinder- 
     >points.size () << " data points." << std::endl;
          writer.write (filename, *cloud_cylinder, false);
      }
      return (0);
    }
    
[/code]

すると一部の点群ファイルに関しては、以下のようなエラーが出るようになりました。もちろん、入力ファイル内に円柱足り得る点群はあるのですが、検出できません。入力ファイルの点群数は出ているので、入力そのものはできていると思うのですが、なぜか円柱パラメータが取得できません。  
どなたか原因がわかる方、いらっしゃいますでしょうか。

[code]

    PointCloud has: 1042 data points.
    PointCloud after filtering has: 0 data points.
    [pcl::NormalEstimation::compute] input_ is empty! 
    [pcl::SampleConsensusModel::getSamples] Can not select 0 unique points out of 0!
    [pcl::RandomSampleConsensus::computeModel] No samples could be selected!
    [pcl::SACSegmentationFromNormals::segment] Error segmenting the model! No solution found.
    Plane coefficients: header: 
    seq: 0 stamp: 0 frame_id: 
    values[]
    
    PointCloud representing the planar component: 0 data points.
    terminate called after throwing an instance of 'pcl::IOException'
      what():  : [pcl::PCDWriter::writeASCII] Input point cloud has no data!
    Aborted (core dumped)
    
[/code]

初心者的質問で申し訳ございませんが、よろしくお願い致します。


CC BY-SA 4.0
2020-10-27T12:17:22.610
71539
2020-10-28T04:40:34.207
20022
question
c++ ubuntu
PCLの円柱検出によるエラーが解決できない


メッセージは、  
「PointCloud has: 1042 data points.  
PointCloud after filtering has: 0 data points.」  
[直訳] １０４２個のデータポイントがありました。  
フィルタリング後、０個のデータポイントになりました。

というものですから、円柱検出をすべきデータが無い状況になっています（データが無いので、円柱抽出が出来ない）。

フィルタリングの過程で、データがどのように推移しているのかを追跡していっては如何でしょう？


CC BY-SA 4.0
2020-10-28T04:40:34.207
71551
2020-10-28T04:40:34.207
217
71539
answer