1

Ich habe eine Punktwolke, die durch Scannen einer planaren Oberfläche mit Stereokameras erzeugt wird. Ich habe Features wie Normale, Fpfh usw. erzeugt und benutze diese Informationen, um Bereiche in der Punktwolke zu klassifizieren. Um die Verwendung herkömmlicher CNN-Ansätze zu ermöglichen, möchte ich diese Pointcloud in opencv in ein Mehrkanalbild konvertieren. Ich habe die Punktwolke auf die XY-Ebene reduziert und auf die X- und Y-Achse ausgerichtet, so dass ich eine Begrenzungsbox für das Bild erstellen kann.Konvertieren einer Punktwolke in ein Tiefen-/Mehrkanalbild

Ich bin auf der Suche nach Ideen, wie Sie weiter mit dem Mapping von Punkten zu Pixeln gehen. Insbesondere bin ich verwirrt über die Bildgröße und darüber, wie man jedes Pixel mit den entsprechenden Daten ausfüllt. (Überlappende Punkte würden gemittelt, leere werden entsprechend gekennzeichnet). Da dies eine unorganisierte Punktwolke ist, habe ich keine Kameraparameter zu verwenden, und ich denke, die RangImage-Klasse von PCL würde in meinem Fall nicht funktionieren.

Jede Hilfe wird geschätzt!

Antwort

0

Versuchen Sie zunächst, eine leere cv :: Mat mit der vorgegebenen Größe zu erstellen. Dann iteriere durch jedes Pixel dieser Matte, um zu bestimmen, welchen Wert es nehmen soll.

Hier einige Code, der etwas Ähnliches tut, was Sie beschreiben:

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; 
} 
Verwandte Themen