博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
连接两个点云中的字段或数据形成新点云以及Opennni Grabber初识
阅读量:5940 次
发布时间:2019-06-19

本文共 6212 字,大约阅读时间需要 20 分钟。

(1)学习如何连接两个不同点云为一个点云,进行操作前要确保两个数据集中字段的类型相同和维度相等,同时了解如何连接两个不同点云的字段(例如颜色 法线)这种操作的强制约束条件是两个数据集中点的数目必须一样,例如:点云A是N个点XYZ点,点云B是N个点的RGB点,则连接两个字段形成点云C是N个点xyzrgb类型

新建文件concatenate_clouds.cpp  CMakeLists.txt

concatenate_clouds.cpp :

 

#include 
#include
//io模块 #include
//数据类型int main (int argc, char** argv){ if (argc != 2) //提示如果执行可执行文件输入两个参数 -f 或者-p { std::cerr << "please specify command line arg '-f' or '-p'" << std::endl; exit(0); } //申明三个pcl::PointXYZ点云数据类型,分别为cloud_a, cloud_b, cloud_c pcl::PointCloud
cloud_a, cloud_b, cloud_c; //存储进行连接时需要的Normal点云,Normal (float n_x, float n_y, float n_z) pcl::PointCloud
n_cloud_b; //存储连接XYZ与normal后的点云 pcl::PointCloud
p_n_cloud_c; // 创建点云数据 //设置cloud_a的个数为5 cloud_a.width = 5; cloud_a.height = cloud_b.height = n_cloud_b.height = 1; //设置都为无序点云 cloud_a.points.resize (cloud_a.width * cloud_a.height); //总数 if (strcmp(argv[1], "-p") == 0) //判断是否为连接a+b=c(点云连接) { cloud_b.width = 3; cloud_b.points.resize (cloud_b.width * cloud_b.height); } else{ n_cloud_b.width = 5; //如果是连接XYZ与normal则生成5个法线(字段间连接) n_cloud_b.points.resize (n_cloud_b.width * n_cloud_b.height); }//以下循环生成无序点云填充上面定义的两种类型的点云数据 for (size_t i = 0; i < cloud_a.points.size (); ++i) { //cloud_a产生三个点(每个点都有X Y Z 三个随机填充的值) cloud_a.points[i].x = 1024 * rand () / (RAND_MAX + 1.0f); cloud_a.points[i].y = 1024 * rand () / (RAND_MAX + 1.0f); cloud_a.points[i].z = 1024 * rand () / (RAND_MAX + 1.0f); } if (strcmp(argv[1], "-p") == 0) for (size_t i = 0; i < cloud_b.points.size (); ++i) { //如果连接a+b=c,则cloud_b用三个点作为xyz的数据 cloud_b.points[i].x = 1024 * rand () / (RAND_MAX + 1.0f); cloud_b.points[i].y = 1024 * rand () / (RAND_MAX + 1.0f); cloud_b.points[i].z = 1024 * rand () / (RAND_MAX + 1.0f); } else for (size_t i = 0; i < n_cloud_b.points.size (); ++i) { //如果连接xyz+normal=xyznormal则n_cloud_b用5个点作为normal数据 n_cloud_b.points[i].normal[0] = 1024 * rand () / (RAND_MAX + 1.0f); n_cloud_b.points[i].normal[1] = 1024 * rand () / (RAND_MAX + 1.0f); n_cloud_b.points[i].normal[2] = 1024 * rand () / (RAND_MAX + 1.0f); }/*******************************************************************定义了连接点云会用到的5个点云对象:3个输入(cloud_a cloud_b 和n_cloud_b)两个输出(cloud_c n_cloud_c)然后就是为两个输入点云cloud_a和 cloud_b或者cloud_a 和n_cloud_b填充数据 ********************************************************************///输出Cloud A std::cerr << "Cloud A: " << std::endl; for (size_t i = 0; i < cloud_a.points.size (); ++i) std::cerr << " " << cloud_a.points[i].x << " " << cloud_a.points[i].y << " " << cloud_a.points[i].z << std::endl;//输出Cloud B std::cerr << "Cloud B: " << std::endl; if (strcmp(argv[1], "-p") == 0) for (size_t i = 0; i < cloud_b.points.size (); ++i) std::cerr << " " << cloud_b.points[i].x << " " << cloud_b.points[i].y << " " << cloud_b.points[i].z << std::endl; else//输出n_Cloud_b for (size_t i = 0; i < n_cloud_b.points.size (); ++i) std::cerr << " " << n_cloud_b.points[i].normal[0] << " " << n_cloud_b.points[i].normal[1] << " " << n_cloud_b.points[i].normal[2] << std::endl; // Copy the point cloud data if (strcmp(argv[1], "-p") == 0) { cloud_c = cloud_a; cloud_c += cloud_b;//把cloud_a和cloud_b连接一起创建cloud_c 后输出 std::cerr << "Cloud C: " << std::endl; for (size_t i = 0; i < cloud_c.points.size (); ++i) std::cerr << " " << cloud_c.points[i].x << " " << cloud_c.points[i].y << " " << cloud_c.points[i].z << " " << std::endl; } else { //连接字段 把cloud_a和 n_cloud_b字段连接 一起创建 p_n_cloud_c) pcl::concatenateFields (cloud_a, n_cloud_b, p_n_cloud_c); std::cerr << "Cloud C: " << std::endl; for (size_t i = 0; i < p_n_cloud_c.points.size (); ++i) std::cerr << " " << p_n_cloud_c.points[i].x << " " << p_n_cloud_c.points[i].y << " " << p_n_cloud_c.points[i].z << " " << p_n_cloud_c.points[i].normal[0] << " " << p_n_cloud_c.points[i].normal[1] << " " << p_n_cloud_c.points[i].normal[2] << std::endl; } return (0);}

 

CMakeLists.txt

cmake_minimum_required(VERSION 2.8 FATAL_ERROR)project(ch2_2)find_package(PCL 1.2 REQUIRED)include_directories(${PCL_INCLUDE_DIRS})link_directories(${PCL_LIBRARY_DIRS})add_definitions(${PCL_DEFINITIONS})add_executable (concatenate_clouds concatenate_clouds.cpp)target_link_libraries (concatenate_clouds ${PCL_LIBRARIES})

编译执行后的结果,仔细研究看一下就可以看出点云连接和字段间连接的区别,字段间连接是在行的基础后连接,而点云连接是在列的下方连接,最重要的就是要考虑维度问题,同时每个点云都有XYZ三个数据值

 

字段间连接:

 点云连接

(2)对于获取传感器的深度信息可以使用OpenNI Grabber类,(其中涉及到如何安装传感器的驱动等问题,比如我使用的是kinect 1.0 可能会遇到一些安装问题,但是网上还是有很多的解决办法的,在这里不对于叙述)

新建文件openni_grabber.cpp

#include 
//点云类定义头文件#include
//点 类型定义头文件#include
//OpenNI数据流获取头文件#include
//时间头文件//类SimpleOpenNIProcessor 的回调函数,作为在获取数据时,对数据进行处理的回调函数的封装,在本例中并没有什么处理,只是实时的在标准输出设备打印处信息。class SimpleOpenNIProcessor{public: void cloud_cb_ (const pcl::PointCloud
::ConstPtr &cloud) { static unsigned count = 0; static double last = pcl::getTime (); //获取当前时间 if (++count == 30) //每30ms一次输出 { double now = pcl::getTime (); // >>右移 std::cout << "distance of center pixel :" << cloud->points [(cloud->width >> 1) * (cloud->height + 1)].z << " mm. Average framerate: " << double(count)/double(now - last) << " Hz" << std::endl; count = 0; last = now; } } void run () { pcl::Grabber* interface = new pcl::OpenNIGrabber(); //创建OpenNI采集对象 // 定义回调函数 boost::function
::ConstPtr&)> f = boost::bind (&SimpleOpenNIProcessor::cloud_cb_, this, _1); boost::signals2::connection c = interface->registerCallback (f);//注册回调函数 interface->start (); //开始接受点云数据 //直到用户按下Ctrl -c while (true) boost::this_thread::sleep (boost::posix_time::seconds (1)); // 停止采集 interface->stop (); }};int main (){ SimpleOpenNIProcessor v; v.run (); return (0);}

CMakeLists.txt

cmake_minimum_required(VERSION 2.8 FATAL_ERROR)project(openni_grabber)find_package(PCL 1.2 REQUIRED)include_directories(${PCL_INCLUDE_DIRS})link_directories(${PCL_LIBRARY_DIRS})add_definitions(${PCL_DEFINITIONS})add_executable (openni_grabber openni_grabber.cpp)target_link_libraries (openni_grabber ${PCL_LIBRARIES})

编译后执行可执行文件的结果如下

微信公众号号可扫描二维码一起共同学习交流

未完待续*******************************************8

转载地址:http://jmqtx.baihongyu.com/

你可能感兴趣的文章
soapUI的简单使用(webservice接口功能测试)
查看>>
框架 Hibernate
查看>>
python-while循环
查看>>
手机端上传图片及java后台接收和ajaxForm提交
查看>>
【MSDN 目录】C#编程指南、C#教程、ASP.NET参考、ASP.NET 4、.NET Framework类库
查看>>
jquery 怎么触发select的change事件
查看>>
angularjs指令(二)
查看>>
(原創) 如何建立一个thread? (OS) (Linux) (C/C++) (C)
查看>>
<气场>读书笔记
查看>>
领域驱动设计,构建简单的新闻系统,20分钟够吗?
查看>>
web安全问题分析与防御总结
查看>>
React 组件通信之 React context
查看>>
ZooKeeper 可视化监控 zkui
查看>>
Linux下通过配置Crontab实现进程守护
查看>>
ios 打包上传Appstore 时报的错误 90101 90149
查看>>
Oracle推出轻量级Java微服务框架Helidon
查看>>
密码概述
查看>>
autoconf,automake,libtool
查看>>
jQuery的技巧01
查看>>
基于泛型实现的ibatis通用分页查询
查看>>