如何将点云投影到地平面上并将其传输到点云库中的2D图像(OpenCV Mat)中? [英] How to project point cloud onto the ground plane and transfer it into an 2D image (OpenCV Mat) in Point Cloud Library?

查看:1383
本文介绍了如何将点云投影到地平面上并将其传输到点云库中的2D图像(OpenCV Mat)中?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想在地面上分割石头,并像这样计算石头的面积:

I want to segment stones on the ground and count the area of the stones like this :

我已经写了2年的OpenCV,发现仅使用OpenCV RGB图片很难对石头进行分割,因此我使用kinect融合技术扫描地面并获得点云,在该点云中,石头高于地面.
我使用点云库对接地平面(绿色)进行分段,如下所示:

I have written OpenCV for 2 years and find it's really hard to segment the stones only using OpenCV RGB picture, so I use kinect fusion to scan the ground and get a point cloud, in which the stones is higher than the ground.
I use the Point Cloud Library to segment the ground plane (in green color) like this:

现在,我正在尝试将其余点投影到地平面上,并以OpenCV Mat格式获取2D图像(原始点的高度成为地面2D图像中投影点的值),结果是是一张灰色的Mat图片.但这对我来说非常困难,您能给我一些建议吗?

Now I am trying to project the rest points onto the ground plane and get a 2D image in OpenCV Mat format(the height of the original point become the value of the projected point in the ground 2D image), which turn out to be a gray Mat picture. But this is very difficult for me, and could you give me some advice?

如果我成功获得了新的灰色Mat,则可以对其进行分割,这对我来说很容易.

If I succeed to get my new gray Mat, then I can do segmentation on it , which is quite easy for me.

顺便说一句,是否有一个点云查看器,我可以看到这些点的(x,y,z)坐标?

by the way, is there a point cloud viewer that I can see the (x,y,z) coordinate of the points?

这是我的主要代码:

pcl::PointCloud<pcl::PointXYZ>::Ptr cloud (new pcl::PointCloud<pcl::PointXYZ>);

pcl::io::loadPLYFile ("MeshedReconstruction.ply", *cloud);

pcl::ModelCoefficients::Ptr coefficients (new pcl::ModelCoefficients);
pcl::PointIndices::Ptr inliers_groud (new pcl::PointIndices);
// Create the segmentation object
pcl::SACSegmentation<pcl::PointXYZ> seg;
// Optional
seg.setOptimizeCoefficients (true);
// Mandatory
seg.setModelType (pcl::SACMODEL_PLANE);
seg.setMethodType (pcl::SAC_RANSAC);
seg.setDistanceThreshold (0.01);//1cm

seg.setInputCloud (cloud);
seg.segment (*inliers_groud, *coefficients);

if (inliers_groud->indices.size () == 0)
{
    PCL_ERROR ("Could not estimate a planar model for the given dataset.");
    return (-1);
}

std::cerr << "Model coefficients: " << coefficients->values[0] << " " 
    << coefficients->values[1] << " "
    << coefficients->values[2] << " " 
    << coefficients->values[3] << std::endl;

std::cerr << "Model inliers_groud: " << inliers_groud->indices.size () << std::endl;

// Create the filtering object
pcl::ExtractIndices<pcl::PointXYZ> extract;
extract.setInputCloud (cloud);
extract.setIndices (inliers_groud);
extract.setNegative(false);

pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_groud (new pcl::PointCloud<pcl::PointXYZ>);

extract.filter (*cloud_groud);//get the ground plane

std::cerr << "Ground cloud after filtering: " << std::endl;
std::cerr << *cloud_groud << std::endl;

pcl::PCDWriter writer;
writer.write<pcl::PointXYZ> ("samp11-utm_ground.pcd", *cloud_groud, false);

我的答案:

查看此PCL api: http://docs.pointclouds.org /1.7.2/a02405.html#ga4375e99ec2ae368eec9379f506568611

Look at this PCL api:http://docs.pointclouds.org/1.7.2/a02405.html#ga4375e99ec2ae368eec9379f506568611

我成功解决了这个问题!

I successfully solved this problem!

结果很好(紫色平面是原始地面,绿色平面是变换的地面平面,即X-O-Y平面):

And the result is great(the purple plane is original ground, and the green plane is transformed ground plane which is the X-O-Y plane):

现在,如果pcl :: PointXYZ为(x0,y0,z0),则Mat(x0,y0)上的点为z0.结果:

Now if a pcl::PointXYZ is (x0, y0, z0), then the point on Mat (x0,y0) is z0. The result:

推荐答案

在谈论将某些东西投射到地面时 平面,通常您需要投影矩阵(K [R | t]).在 你的情况,如果我理解正确的话,你想做一个正交的 投影,这意味着您要松开Z坐标: http://en.wikipedia.org/wiki/Orthographic_projection

when you're talking about projecting something into the ground plane, usually you will need the projection matrix (K [R|t]). In your case, if I understood correctly, you want to do a orthogonal projection, which means you want to loose the Z coordinate: http://en.wikipedia.org/wiki/Orthographic_projection

现在,适合您的情况的方程式将是这样

Now, the equation for you case will be something like this

z_max = max z(Pts[x,y,z])
im[x,y] = z_max

请注意,您需要搜索最大高度(Z) 在您的云中给定的x-y点.

Notice here that you will need to search for the max height (Z) in a given x-y point in your cloud.

希望这对您有帮助...

I hope this helps you...

这篇关于如何将点云投影到地平面上并将其传输到点云库中的2D图像(OpenCV Mat)中?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆