2017-09-06 63 views
0

私はpcl :: pointcloudの平面セクションをバイナリイメージに変換しようとしています。私はsavePNGFileというクラスを見つけましたが、私のプログラムでうまく動作しません。pcl :: pointcloudをバイナリイメージに変換します。 C++

これまでは、私が望むポイントを得るためにROIセレクターと輝度フィルタを行っていました。

void regionOfInterest(VPointCloud::Ptr cloud_in, double x1, double x2, 
double y1, double y2, double z) 
{ 
    for (VPoint& point: cloud_in->points) 
    if ((z > point.z) && (y1 > point.y) && (y2 < point.y) && (x1 > point.x) 
    &&(x2 < point.x)) 
     cloud_out->points.push_back(point); 
} 

私は、関連するIが示すコードの一部が存在しないかもしれないことを知っている (VPointCloudは、私は私のデータを操作する必要があるpointcloudの一種である)、それはあなたが多かれ少なかれタイプI」は表示することができますを使用しています。

誰もがこのpointcloudをバイナリイメージにエクスポートする方法を知っていますか?このステップの後、私はOpenCVで作業します。

ありがとうございました

+0

は、pointcloud構造または非構造化です –

+0

これはdicomデータと思われますか?その場合は構造化する必要があります –

+0

バイナリイメージとはどういう意味ですか?投影されたカメラのピクセルが点を見たかどうか?またはフィルタリングされたポイントで奥行き画像が必要ですか?いずれにせよ、[雲からの距離画像](http://pointclouds.org/documentation/tutorials/range_image_creation.php)または[点群から画像へ](http://wiki.ros.org/ pcl_ros/Tutorials/CloudToImage)?さらに、[パススルーフィルタ](http://pointclouds.org/documentation/tutorials/passthrough.php)をチェックしてください。 – apalomer

答えて

0

この方法は、組織化されたデータまたは未編成のデータのどちらでも有効です。ただし、入力点クラウド平面を回転させて、直交する2つの次元に平行にし、削除する次元を知っている必要があります。 stepSize1とstepSize2は、ポイントクラウドのどのサイズが新しい画像のピクセルになるかを設定するパラメータです。これは、点密度に基づいてグレースケール画像を計算しますが、深さやその他の情報を表示するように簡単に変更できます。単純な閾値を用いて画像をバイナリにすることもできる。

cv::Mat makeImageFromPointCloud(pcl::PointCloud<pcl::PointXYZ>::Ptr cloud, std::string dimensionToRemove, float stepSize1, float stepSize2) 
{ 
    pcl::PointXYZI cloudMin, cloudMax; 
    pcl::getMinMax3D(*cloud, cloudMin, cloudMax); 

    std::string dimen1, dimen2; 
    float dimen1Max, dimen1Min, dimen2Min, dimen2Max; 
    if (dimensionToRemove == "x") 
    { 
     dimen1 = "y"; 
     dimen2 = "z"; 
     dimen1Min = cloudMin.y; 
     dimen1Max = cloudMax.y; 
     dimen2Min = cloudMin.z; 
     dimen2Max = cloudMax.z; 
    } 
    else if (dimensionToRemove == "y") 
    { 
     dimen1 = "x"; 
     dimen2 = "z"; 
     dimen1Min = cloudMin.x; 
     dimen1Max = cloudMax.x; 
     dimen2Min = cloudMin.z; 
     dimen2Max = cloudMax.z; 
    } 
    else if (dimensionToRemove == "z") 
    { 
     dimen1 = "x"; 
     dimen2 = "y"; 
     dimen1Min = cloudMin.x; 
     dimen1Max = cloudMax.x; 
     dimen2Min = cloudMin.y; 
     dimen2Max = cloudMax.y; 
    } 

    std::vector<std::vector<int>> pointCountGrid; 
    int maxPoints = 0; 

    std::vector<pcl::PointCloud<pcl::PointXYZ>::Ptr> grid; 

    for (float i = dimen1Min; i < dimen1Max; i += stepSize1) 
    { 
     pcl::PointCloud<pcl::PointXYZ>::Ptr slice = passThroughFilter1D(cloud, dimen1, i, i + stepSize1); 
     grid.push_back(slice); 

     std::vector<int> slicePointCount; 

     for (float j = dimen2Min; j < dimen2Max; j += stepSize2) 
     { 
      pcl::PointCloud<pcl::PointXYZ>::Ptr grid_cell = passThroughFilter1D(slice, dimen2, j, j + stepSize2); 

      int gridSize = grid_cell->size(); 
      slicePointCount.push_back(gridSize); 

      if (gridSize > maxPoints) 
      { 
       maxPoints = gridSize; 
      } 
     } 
     pointCountGrid.push_back(slicePointCount); 
    } 

    cv::Mat mat(static_cast<int>(pointCountGrid.size()), static_cast<int>(pointCountGrid.at(0).size()), CV_8UC1); 
    mat = cv::Scalar(0); 

    for (int i = 0; i < mat.rows; ++i) 
    { 
     for (int j = 0; j < mat.cols; ++j) 
     { 
      int pointCount = pointCountGrid.at(i).at(j); 
      float percentOfMax = (pointCount + 0.0)/(maxPoints + 0.0); 
      int intensity = percentOfMax * 255; 

      mat.at<uchar>(i, j) = intensity; 
     } 
    } 

    return mat; 
} 


pcl::PointCloud<pcl::PointXYZ>::Ptr passThroughFilter1D(const pcl::PointCloud<pcl::PointXYZ>::Ptr cloud, const std::string field, const double low, const double high, const bool remove_inside) 
{ 
    if (low > high) 
    { 
     std::cout << "Warning! Min is greater than max!\n"; 
    } 

    pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_filtered(new pcl::PointCloud<pcl::PointXYZI>); 
    pcl::PassThrough<pcl::PointXYZI> pass; 

    pass.setInputCloud(cloud); 
    pass.setFilterFieldName(field); 
    pass.setFilterLimits(low, high); 
    pass.setFilterLimitsNegative(remove_inside); 
    pass.filter(*cloud_filtered); 
    return cloud_filtered; 
} 
関連する問題