1

ステレオカメラを使用して平面をスキャンすることによってポイントクラウドを生成しました。私は法線、fpfhなどの特徴を生成し、この情報を使ってポイントクラウド内のエリアを分類したいと考えています。より伝統的なCNNアプローチを使用できるようにするために、このpointcloudをopencvのマルチチャネルイメージに変換したいと考えています。ポイントクラウドをXY平面に崩壊させ、X軸とY軸に整列させて、イメージの境界ボックスを作成できるようにします。ポイントクラウドを深度/マルチチャンネル画像に変換する

私は、ポイントからピクセルへのマッピングをさらに進める方法についてアイデアを探しています。具体的には、イメージのサイズと、各ピクセルに適切なデータを入力する方法について混乱します。 (重複する点は平均化され、空のものはそれに応じてラベル付けされます)。これは組織化されていないポイントクラウドなので、私は使用するカメラパラメータを持っていないので、PCLのRangImageクラスが私の場合にはうまくいかないと思います。

ご協力いただきましてありがとうございます。

答えて

0

まず、所定のサイズの空のcv :: Matを作成してみてください。そのMatのすべてのピクセルを繰り返して、どの値を取るべきかを決定します。ここで

あなたが記述されたものに似た何かをするいくつかのコードです:

cv::Mat makeImageFromPointCloud(pcl::PointCloud<pcl::PointXYZI>::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<upcloud> grid; 

    for (float i = dimen1Min; i < dimen1Max; i += stepSize1) 
    { 
     pcl::PointCloud<pcl::PointXYZI>::Ptr slice = upcl::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::PointXYZI>::Ptr grid_cell = upcl::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; 
}