如何将点云投影到地平面上并将其转换为点云库中的2D图像(OpenCV Mat)?

问题描述 投票:0回答:1

我想在地面上分割石头并计算石头的面积,如下所示:

我已经写了2年的OpenCV,并发现仅使用OpenCV RGB图片分割石头真的很难,所以我使用kinect融合扫描地面并得到一个点云,其中石头高于地面。 我使用点云库来分割地平面(绿色),如下所示:

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

如果我成功获得了我的新灰色Mat,那么我可以对它进行分割,这对我来说非常容易。

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

这是我的主要代码:

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

我成功解决了这个问题!

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

现在,如果pcl :: PointXYZ是(x0,y0,z0),那么Mat(x0,y0)上的点是z0。结果:

c++ opencv kinect point-cloud-library
1个回答
0
投票

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

现在,你的方程式将是这样的

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

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

我希望这可以帮助你...

© www.soinside.com 2019 - 2024. All rights reserved.