如何从深度图像中提取边界
博客转载自:http://www.pclcn.org/study/shownews.php?lang=cn&id=206
本小节中一起学习如何从深度图像中提取边界(从前景跨越到背景的位置定义为边界)。我们对三种类型的点集感兴趣:物体边界,这是物体最外层和阴影边界的可见点集;阴影边界,毗连于遮挡的背景上的点集;Veil点集,在被遮挡物边界和阴影边界之间的内插点,它们是由激光雷达获取的3D距离数据中的典型数据类型。这三类数据及深度图像的边界如图1所示。
代码
首先,在PCL(Point Cloud Learning)中国协助发行的书提供光盘的第9章例2文件夹中,打开名为range_image_border_extraction.cpp的代码文件,同文件夹下有测试点云文件。
解释说明
首先,我们进行命令行解析,然后,从磁盘中读取点云(或者如果没有提供,则创建一个点云),最后,创建深度图像并使其可视化。提取边界信息时很重要的一点是区分深度图像中的当前视点不可见点集合和应该可见但处于传感器获取距离范围外的点集,后者可以标记为典型边界,然而当前视点不可见点则不能成为边界。因此,如果后者的测量值存在,则提供那些超出传感器距离获取范围外的数据对于边界提取是非常有用的,我们希望找到另外的包含这些值的pcd文件,这里代码中用far_range.pcd作为这类数据的实例。
std::string far_ranges_filename = pcl::getFilenameWithoutExtension (filename)+"_far_ranges.pcd"; if (pcl::io::loadPCDFile(far_ranges_filename.c_str(), far_ranges) == -1) std::cout << "Far ranges file \""<<far_ranges_filename<<"\" does not exists.\n";
使用以下代码之后将它们并入到深度图像中。
range_image.integrateFarRanges (far_ranges);
如果用户没有这些远距离的点云,则可采用命令行参数-m,这样设置所有不能观察到的点都为远距离的,下代码来执行这一步:
if (setUnseenToMaxRange) range_image.setUnseenToMaxRange ();
现在我-们来看与实际边界抽取相关的这一部分。
pcl::RangeImageBorderExtractor border_extractor (&range_image); pcl::PointCloud<pcl::BorderDescription> border_descriptions; border_extractor.compute (border_descriptions);
此部分创建了RangeImageBorderExtractor这个对象,给了它深度图像,并且计算后存储边界信息在border_descriptions中(详见BorderDescription 结构中的common/include/pcl/point_types.h),余的代码只是用来可视化的。
编译和运行程序
利用光盘提供的CMakeLists.txt文件,在cmake中建立工程文件,并生成相应的可执行文件。生成执行文件后,就可以运行了,在cmd中键入命令:
...>range_image_border_extraction.exe -m
这将使用一个自动生成的、矩形状浮点型点云,运行结果如图1所示,检测出的边缘点用绿色较大的点表示,其他点用默认的黑色普通大小点表示。也可以使用用户磁盘中的一个实际点云来运行该程序:
图1 无点云输入时边缘检测运行结果
图2用户指定点云边缘检测结果
敬请关注PCL(Point Cloud Learning)中国更多的点云库PCL(Point Cloud Library)相关官方教程。
参考文献:
1.朱德海、郭浩、苏伟.点云库PCL学习教程(ISBN 978-7-5124-0954-5)北京航空航天出版社2012-10