您的位置:首页 > 理论基础

使用PCL的IntegralImageNormalEstimation遇到的vector subsript out of range问题

2015-12-21 13:32 1146 查看
转载请注明出处:http://my.csdn.net/ye_shen_wei_mian

生平第一篇博客,有点小激动,写的不好还望多多包涵,也欢迎分享更好的解决办法和思路。。。

网上关于PCL(Point Cloud Library)这个库的资料确实少之又少,遇到有的比较难解决的bug只能上csdn,stackoverflow上面各种找解决方法,还有PCL user mailing list,这是个不错的PCL开发者讨论区。

解决问题的过程非常的花时间和精力,因此希望能够通过分享自己遇到的问题,来免去后来者在同样的问题上再走一遍同样的路的痛苦,同时也欢迎大家提出更好的解决方案和思路撒~~~

最近因为课题的原因,要使用到PCL库中的IntegralImageNormalEstimation进行表面法线的预测。

代码如下(代码仅供参考,可以上PCL的官网上查阅相应的例程):

pcl::PointCloud<pcl::PointXYZI>::Ptr cloud_ptr(new pcl::PointCloud<pcl::PointXYZI>);

*cloud_ptr = cloud_;

pcl::PointCloud<pcl::Normal>::Ptr cloud_normals_ptr(new pcl::PointCloud<pcl::Normal>);

pcl::IntegralImageNormalEstimation<pcl::PointXYZI, pcl::Normal> ne;

ne.setNormalEstimationMethod(ne.AVERAGE_3D_GRADIENT);

ne.setMaxDepthChangeFactor(0.02f);

ne.setNormalSmoothingSize(10.0f);

ne.setInputCloud(cloud_ptr);

cout << "test12" << endl;

ne.compute(*cloud_normals_ptr);

cout << "test13" << endl;

cloud_normals_ = *cloud_normals_ptr;

代码大致的意思就是,首先由Kinect采集到的深度图生成对应的cloud_,然后对cloud_这个点云使用IntegralImageNormalEstimation进行法线的估计,估计的方法使用的是AVERAGE_3D_GRADIENT。

然而,出现了非常奇怪的情况,在对一开始使用到的深度图使用IntegralImageNormalEstimation进行法线估计的时候,并没有出现问题。但之后更换深度图再进行一模一样的处理时,就报出了vector subsript out of range的错误。后来经输出结果查看,是ne.compute(*cloud_normals_ptr);这句话发生了问题。

弄了很久没弄出来,一直很困惑,但是之后通过对点云可视化的结果,发现了一些端倪,尝试着再使用KInect拍摄可能适用的深度图,居然又没报错了。所以虽然由于本人水平有限,没办法通过严谨细致的理论分析给出一个非常有效的解决方案,但是还是可以分享一下这个问题的一个权宜的解决方法。

我们先看看有问题(报错)的场景和它的点云是怎么样的,

场景RGB图:



相应的点云图:



我们再看看不报错的场景和它的点云是什么样的,

场景RGB图:



相应的点云图(使用PCL的cloudviewer来可视化的):



报错的那个场景的点云图,由于场景上方时较远的天花板,于是生成的点云在上方会有较大的向后的延伸。而反观没有报错的场景,场景最远也是Kinect可以探测到的墙壁,是有限远(Kinect可以探测到的)深度范围。点云的形态并不相同,而可以作合理的推测是,PCL这个IntegralImageNormalEstimation类对场景应该是有一定的假设和要求的,并不是所有的场景生成的点云都可以进行法线的估计。所以在选择场景时,应当尽量选择有限远的(例如墙壁之类的)场景,应该就可以作为权宜之计。

再次强调的是,以上仅仅是根据实验结果的观察和分析做出合理的推断,提供一种可行的权宜之策,如果有读者能提出严谨和万全的解决思路和方法,欢迎评论留言,分享你的解决思路。

谢谢各位的阅览。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息