我通过使用立体摄像头扫描平面表面生成了一个点云。我已经生成了法向量、FPFH等特征,并希望利用这些信息对点云中的区域进行分类。为了能够使用更传统的CNN方法,我希望将这个点云转换为OpenCV中的多通道图像。我已经将点云投影到XY平面,并对齐到X和Y轴,以便为图像创建边界框。
我正在寻找有关如何将点映射到像素的进一步想法。具体来说,我对图像大小感到困惑,以及如何用适当的数据填充每个像素。(重叠的点将被平均处理,空的点将被相应标记)。由于这是一个无组织的点云,我没有相机参数可以使用,我猜PCL的RangeImage类在我这里是行不通的。
任何帮助都将不胜感激!
回答:
尝试先创建一个预定大小的空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<pcl::PointCloud<pcl::PointXYZI>::Ptr> grid; for (float i = dimen1Min; i < dimen1Max; i += stepSize1) { pcl::PointCloud<pcl::PointXYZI>::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::PointXYZI>::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;}