【问题标题】:Converting a pointcloud to a depth/multi channel image将点云转换为深度/多通道图像
【发布时间】:2018-04-15 12:35:51
【问题描述】:

我有一个通过使用立体相机扫描平面表面生成的点云。我已经生成了诸如法线、fpfh 等特征,并使用这些信息对点云中的区域进行分类。为了能够使用更传统的 CNN 方法,我想将此点云转换为 opencv 中的多通道图像。我将点云折叠到 XY 平面,并与 X 轴和 Y 轴对齐,这样我就可以为图像创建一个边界框。

我正在寻找有关如何进一步处理从点到像素的映射的想法。具体来说,我对图像大小以及如何用适当的数据填充每个像素感到困惑。 (重叠的点将被平均,空的点将被相应地标记)。由于这是一个无组织的点云,我没有要使用的相机参数,而且我猜 PCL 的 RangImage 类在我的情况下不起作用。

感谢任何帮助!

【问题讨论】:

    标签: opencv machine-learning 3d computer-vision point-cloud-library


    【解决方案1】:

    先尝试创建一个预定大小的空 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;
    }
    

    【讨论】:

    猜你喜欢
    • 2023-03-21
    • 1970-01-01
    • 2020-07-01
    • 1970-01-01
    • 1970-01-01
    • 2016-09-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多