Ask Your Question

Revision history [back]

click to hide/show revision 1
initial version

cv::Mat to PCL point cloud, to data ptr?

I have a cv::Mat that is a depth image.

I am converting it to a PCL pointcloud like this:

PointCloud::Ptr RGBDtoPCL3(cv::Mat depth_image)
{
    PointCloud::Ptr pointcloud(new PointCloud);

    float fx = 481.20;
    float fy = 480.00;
    float cx = 319.50;
    float cy = 239.50;

    float factor = 1;
    depth_image.convertTo(depth_image, CV_32F); // convert the image data to float type 

    if (!depth_image.data) {
        std::cerr << "No depth data!!!" << std::endl;
        exit(EXIT_FAILURE);
    }

    pointcloud->width = depth_image.cols; //Dimensions must be initialized to use 2-D indexing 
    pointcloud->height = depth_image.rows;

    pointcloud->points.resize(pointcloud->height * pointcloud->width);
    pointcloud->resize(pointcloud->width*pointcloud->height);

    for (int v = 0; v < depth_image.rows; v++)
    {
        for (int u = 0; u < depth_image.cols; u++)
        {
            float Z = depth_image.at<float>(v, u) / factor;

            PointT p;
            p.z = Z;
            p.x = (u - cx) * Z / fx;
            p.y = (v - cy) * Z / fy;

            p.z = p.z / 1000;
            p.x = p.x / 1000;
            p.y = p.y / 1000;

            pointcloud->points.push_back(p);

        }
    }

    return pointcloud;

}

I am also getting the data from the Mat like this:

unsigned short* dataMat1 = depth_image.ptr<unsigned short>();

What i need to do now is Convert the pointcloud into an unsigned short * that matches the dataMat1 above.

What would this conversion look like?

Does the depth_image.ptr<unsigned short> just read row 0: col1, col2, col3.... row 1: col1,col2etc?

Thank you!

cv::Mat to PCL point cloud, to data ptr?

I have a cv::Mat that is a depth image.

I am converting it to a PCL pointcloud like this:

PointCloud::Ptr RGBDtoPCL3(cv::Mat depth_image)
PointcloudUtils::RGBDtoPCL(cv::Mat depth_image, Eigen::Matrix3f& _intrinsics)
{
    PointCloud::Ptr pointcloud(new PointCloud);

    float fx = 481.20;
_intrinsics(0, 0);
    float fy = 480.00;
_intrinsics(1, 1);
    float cx = 319.50;
_intrinsics(0, 2);
    float cy = 239.50;
_intrinsics(1, 2);

    float factor = 1;
     depth_image.convertTo(depth_image, CV_32F); // convert the image data to float type 

    if (!depth_image.data) {
        std::cerr << "No depth data!!!" << std::endl;
        exit(EXIT_FAILURE);
    }

    pointcloud->width = depth_image.cols; //Dimensions must be initialized to use 2-D indexing 
    pointcloud->height = depth_image.rows;

    pointcloud->points.resize(pointcloud->height * pointcloud->width);
    pointcloud->resize(pointcloud->width*pointcloud->height);

#pragma omp parallel for
    for (int v = 0; v < depth_image.rows; v++)
v ++)
    {
        for (int u = 0; u < depth_image.cols; u++)
u ++)
        {
            float Z = depth_image.at<float>(v, u) / factor;

            PointT p;
            p.z = Z;
            p.x = (u - cx) * Z / fx;
            p.y = (v - cy) * Z / fy;

            p.z = p.z / 1000;
            p.x = p.x / 1000;
            p.y = p.y / 1000;

            pointcloud->points.push_back(p);

        }
    }

    return pointcloud;

}

I am also getting the data from the Mat like this:

unsigned short* dataMat1 = depth_image.ptr<unsigned short>();

What i need to do now is Convert the pointcloud into an unsigned short * that matches the dataMat1 above.

What would this conversion look like?

Does the depth_image.ptr<unsigned short> just read row 0: col1, col2, col3.... row 1: col1,col2etc?

Thank you!

EDIT:

To simplify the problem, i am trying to get the pcl - to - Mat conversion working. I load my image, run the above code to get a pointcloud, then take that pointcloud and run:

void PointcloudUtils::PCL2Mat(PointCloud::Ptr pointcloud, cv::Mat& depth_image, int original_width, int original_height, int original_channels)
{
    if (!depth_image.empty())
        depth_image.release();

    depth_image.create(original_height, original_width, CV_32F);

    int count = 0;

#pragma omp parallel for
    for (int v = 0; v < depth_image.rows; ++v)
    {
        for (int u = 0; u < depth_image.cols; ++u)
        {
            depth_image.at<float>(v, u) = pointcloud->points.at(count++).z * 1000;

        }
    }

    depth_image.convertTo(depth_image, CV_8U);

}

I pass that function:

cv::Mat newDepth;
PCL2Mat(newCloud, newDepth, depth_image.cols, depth_image.rows, depth_image.channels());

(where depth_image is the original loaded image). But When i view the newly created mat, it is solid black. Where am i going wrong?

thanks!

cv::Mat to PCL point cloud, to data ptr?

I have a cv::Mat that is a depth image.

I am converting it to a PCL pointcloud like this:

PointCloud::Ptr PointcloudUtils::RGBDtoPCL(cv::Mat depth_image, Eigen::Matrix3f& _intrinsics)
{
    PointCloud::Ptr pointcloud(new PointCloud);

    float fx = _intrinsics(0, 0);
    float fy = _intrinsics(1, 1);
    float cx = _intrinsics(0, 2);
    float cy = _intrinsics(1, 2);

    float factor = 1;

    depth_image.convertTo(depth_image, CV_32F); // convert the image data to float type 

    if (!depth_image.data) {
        std::cerr << "No depth data!!!" << std::endl;
        exit(EXIT_FAILURE);
    }

    pointcloud->width = depth_image.cols; //Dimensions must be initialized to use 2-D indexing 
    pointcloud->height = depth_image.rows;
    pointcloud->resize(pointcloud->width*pointcloud->height);

#pragma omp parallel for
    for (int v = 0; v < depth_image.rows; v ++)
    {
        for (int u = 0; u < depth_image.cols; u ++)
        {
            float Z = depth_image.at<float>(v, u) / factor;

            PointT p;
            p.z = Z;
            p.x = (u - cx) * Z / fx;
            p.y = (v - cy) * Z / fy;

            p.z = p.z / 1000;
            p.x = p.x / 1000;
            p.y = p.y / 1000;

            pointcloud->points.push_back(p);

        }
    }

    return pointcloud;

}

I am also getting the data from the Mat like this:

unsigned short* dataMat1 = depth_image.ptr<unsigned short>();

What i need to do now is Convert the pointcloud into an unsigned short * that matches the dataMat1 above.

What would this conversion look like?

Does the depth_image.ptr<unsigned short> just read row 0: col1, col2, col3.... row 1: col1,col2etc?

Thank you!

EDIT:

To simplify the problem, i am trying to get the pcl - to - Mat conversion working. I load my image, run the above code to get a pointcloud, then take that pointcloud and run:

void cv::Mat PointcloudUtils::PCL2Mat(PointCloud::Ptr pointcloud, cv::Mat& depth_image, int original_width, int original_height, int original_channels)
original_height)
{
    if (!depth_image.empty())
        depth_image.release();

    depth_image.create(original_height, cv::Mat depth_image(original_height, original_width, CV_32F);

//  depth_image.create

    int count = 0;

#pragma omp parallel for
    for (int v = 0; v < depth_image.rows; ++v)
    {
        for (int u = 0; u < depth_image.cols; ++u)
        {
            depth_image.at<float>(v, u) = pointcloud->points.at(count++).z * 1000;

        }
    }

    depth_image.convertTo(depth_image, normalize(depth_image, depth_image, 0, 255, cv::NORM_MINMAX, CV_8U);

    return depth_image;

}

I pass that function:

cv::Mat newDepth;
PCL2Mat(newCloud, newDepth, newDepth = pointcloudUtils_.PCL2Mat(newCloud, depth_image.cols, depth_image.rows, depth_image.channels());
depth_image.rows);
cv::imshow("new", newDepth);
cv::waitKey(1);

(where depth_image is the original loaded image). But When i view the newly created mat, it is solid black. Where am i going wrong?

thanks!