【问题标题】:transform a pcl::pointcloud to binary image. c++将 pcl::pointcloud 转换为二进制图像。 C++
【发布时间】:2017-09-08 00:50:23
【问题描述】:

我正在尝试将 pcl::pointcloud 的平面部分转换为二进制图像。我找到了一个名为 savePNGFile 的类,但与我的程序不兼容。

到目前为止,我做了一个 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);
}

(VPointCloud 是我需要处理我的数据的那种点云) 我知道我展示的那段代码可能不相关,但它可以或多或少地向您展示我正在使用的类型。

有人知道如何将此点云导出为二进制图像吗?在这一步之后,我将使用 OpenCV。

谢谢

【问题讨论】:

  • 点云是结构化的还是非结构化的
  • 我认为这是 dicom 数据?在这种情况下,它应该是结构化的
  • 二值图像是什么意思?投影相机上的像素是否看到了一个点?还是您想要带有过滤点的深度图像?无论如何,你看过range image from point cloudpoint cloud to image吗?此外,您应该检查passthrough filter
  • 很抱歉错过了这么多信息,我将从头开始:首先我从 pcd 文件中获取点云。我应用了过滤器,我得到了一个较小的点云,所有的点都是白色的,深度几乎为 0。现在我想应用深度学习来获取图像中存在对象的位置,但我需要一个图像(二进制图像,数组0 和 1) 将其通过 DL 算法
  • 是的,我明白你想要做什么,但我的问题是结构问题。有就需要使用,没有就需要人为的创建才能制作图片

标签: c++ point-cloud-library binary-image


【解决方案1】:

此方法适用于有组织或无组织的数据。但是,您可能需要旋转输入点云平面,使其平行于两个正交维度,并且您知道要删除的维度。 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;
}

【讨论】:

  • pcl::passThroughFilter1D 不存在!那不应该是pcl::PassThrough吗?
  • 这是我创建的自定义方法,定义在代码sn -p的底部
猜你喜欢
  • 2015-03-26
  • 1970-01-01
  • 2015-12-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-10-16
  • 2014-06-07
相关资源
最近更新 更多