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

新建文件concatenate_clouds.cpp  CMakeLists.txt

concatenate_clouds.cpp :

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

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 <pcl/point_cloud.h>   //点云类定义头文件
#include <pcl/point_types.h> //点 类型定义头文件
#include <pcl/io/openni_grabber.h> //OpenNI数据流获取头文件
#include <pcl/common/time.h> //时间头文件 //类SimpleOpenNIProcessor 的回调函数,作为在获取数据时,对数据进行处理的回调函数的封装,在本例中并没有什么处理,只是实时的在标准输出设备打印处信息。
class SimpleOpenNIProcessor
{
public:
void cloud_cb_ (const pcl::PointCloud<pcl::PointXYZRGBA>::ConstPtr &cloud)
{
static unsigned count = ;
static double last = pcl::getTime (); //获取当前时间
if (++count == ) //每30ms一次输出
{
double now = pcl::getTime ();
// >>右移
std::cout << "distance of center pixel :" << cloud->points [(cloud->width >> ) * (cloud->height + )].z << " mm. Average framerate: " << double(count)/double(now - last) << " Hz" << std::endl;
count = ;
last = now;
}
} void run ()
{
pcl::Grabber* interface = new pcl::OpenNIGrabber(); //创建OpenNI采集对象 // 定义回调函数
boost::function<void (const pcl::PointCloud<pcl::PointXYZRGBA>::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 ()); // 停止采集
interface->stop ();
}
}; int main ()
{
SimpleOpenNIProcessor v;
v.run ();
return ();
}

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

连接两个点云中的字段或数据形成新点云以及Opennni Grabber初识的更多相关文章

  1. 关于left join连接查询 两张表里有同名字段的问题

    左连接查询在开发中很常用,但有个问题常常会遇到,两个表中有同名字段时,比如左右表都有一个id字段,会造成查询结果中左表的id值被右表的id值覆盖掉(大部分php框架都是这个效果),而且还不会报错,容易 ...

  2. JavaScript concat() 方法-连接两个或多个数组

    一,定义和用法 concat() 方法用于连接两个或多个数组. 该方法不会改变现有的数组,而仅仅会返回被连接数组的一个副本. 语法 arrayObject.concat(arrayX,arrayX,. ...

  3. Linq to Entity中连接两个数据库时要注意的问题

    Linq to Entity中连接两个数据库时要注意的问题 今天大学同学问了我一个问题,Linq to Entity中连接两个数据库时,报错“指定的 LINQ 表达式包含对与不同上下文关联的查询的引用 ...

  4. Android 通过外键连接两个数据库

    Learn: 1.Android数据库的语法. 2.通过外键连接两个数据库. 3.加强了对数据库的熟悉度. 4.对文本框的visiblity属性的了解. Demo:http://pan.baidu.c ...

  5. 表A中有两个表示时间的字段A,B;如果B的值大于A的值,则把B的值更新为A的值

    sql语句:表A中有两个表示时间的字段A,B:如果B的值大于A的值,则把B的值更新为A的值 update 表名 set B=A where B>A

  6. DirectX:函数连接两个随机filter

    函数连接两个随机filter HRESULT ConnectFilters( IBaseFilter *pSrc, IBaseFilter *pDest ) { IPin *pIn = 0; IPin ...

  7. mysql 连接两列

    以下划线符号,连接两列,作为查询结果: SELECT CONCAT(col_1,'_',col_2) FROM yourtable

  8. [转载]INNER JOIN连接两个表、三个表、五个表的SQL语句

    SQL INNER JOIN关键字表示在表中存在至少一个匹配时,INNER JOIN 关键字返回行. 1.连接两个数据表的用法: FROM Member INNER JOIN MemberSort O ...

  9. 怎么用ChemDraw连接两个结构片段

    作为最新版的ChemOffice 15.1的核心组件,ChemDraw几乎能解决所有平面化学结构中的绘制问题.如果用户想连接两个分开的结构片段,ChemDraw提供两种连接两个化学结构片段的方法,分别 ...

随机推荐

  1. eclipse jdk版本设置

    1 Java Build Path(项目的编写环境配置): 在项目上单击右键,properties -> Java Build Path -> Libraries,选择JRE System ...

  2. msf web_delivery模块攻击

    目标机:win7                    ip:192.168.31.136 攻击机:kai liunx                      ip:192.168.31.54 一. ...

  3. [CTCI] 下一个较大元素

    下一个较大元素 题目描述 现在我们有一个int数组,请你找出数组中每个元素的下一个比它大的元素. 给定一个int数组A及数组的大小n,请返回一个int数组,代表每个元素比他大的下一个元素,若不存在则为 ...

  4. 用Power BI观察经济与健康的关系

    Hans Rosling是卡罗琳学院的国际卫生学教授.这位学者与众不同的技能是数据可视化.以直观的数据展现了令人信服的世界观,而且在gapminder.org提供无偿展示以及下载.假设你没有看过下面的 ...

  5. Atitti cto的日常流程与职责attilax总结

    Atitti cto的日常流程与职责attilax总结 1. (最重要)技术战略制定 规划,预测趋势1 1.1. 关键词 Throught技术雷达 趋势 没落  已死  辉煌 未来1 1.2. (比较 ...

  6. IOS 设备备份文件详解 (二)

    这篇主要讲解如何解析Manifest.mbdb文件. 使用二进制工具打开这个文件,文件的头6个字节是固定的,相当于是文件的一种标识 后面的内容是一个一个的项,可以使用一个循环来读取文件,一个一个解析. ...

  7. Android Lock Pattern 图案解锁

    参考链接:http://www.cnblogs.com/dyingbleed/archive/2012/12/03/2800007.html http://blog.csdn.net/way_ping ...

  8. centos7 开启特定的端口

    systemctl是centos7的服务管理工具中主要的工具,它融合之前的service和chkconfig功能于一体; 开机时启动:systemctl enable firewalld.servic ...

  9. 【内核】linux2.6版本内核编译配置选项(一)

    Linux 2.6.19.x 内核编译配置选项简介 作者:金步国 版权声明 本文作者是一位自由软件爱好者,所以本文虽然不是软件,但是本着 GPL 的精神发布.任何人都可以自由使用.转载.复制和再分发, ...

  10. Spring和Mybatis整合过程中遇到的一个找不到sqlSessionFactory或sqlSessionTemplate的异常

    先看启动web项目时IDEA控制台抛出的异常(红色部分): D:\tomcat-kafka-\bin\catalina.bat run [-- ::,] Artifact Gradle : com.x ...