PCL的I/O操作(OpenNI)

从PCD文件中读取点云数据
代码:

#include <iostream>
#include <pcl/io/pcd_io.h>
#include <pcl/point_types.h>

int main(int argc,char** argv)
{
pcl::PointCloud<pcl::PointXYZ>::Ptr cloud (new pcl::PointCloud<pcl::PointXYZ>);

if(pcl::io::loadPCDFile<pcl::PointXYZ>("test_pcd.pcd",*cloud)==-1)
{
PCL_ERROR("Couldn't read file test_pcd.pcd\n");
return(-1);
}
std::cout<<"Loaded "<<cloud->width*cloud->height<<" data points from test_pcd.pcd with the following fields: "<<std::endl;
for(size_t i=0;i<cloud->points.size();++i)
std::cout<<"    "<<cloud->points[i].x<<" "<<cloud->points[i].y<<" "<<cloud->points[i].z<<std::endl;

return(0);
}

test_pcd.pcd文件要写上路径;

size_t在32位架构上是4字节,在64位架构上是8字节,在不同架构上进行编译时需要注意这个问题。而int在不同架构下都是4字节,与size_t不同;且int为带符号数,size_t为无符号数。

为什么有时候不用int,而是用size_type或者size_t:
与int固定四个字节不同有所不同,size_t的取值range是目标平台下最大可能的数组尺寸,一些平台下size_t的范围小于int的正数范围,又或者大于unsigned int. 使用int既有可能浪费,又有可能范围不够大。

Boost共享指针的使用,动态内存new,size_t 见下图:
在这里插入图片描述new的更详细用法见链接:
https://www.runoob.com/cplusplus/cpp-dynamic-memory.html (菜鸟教程)

strcmp(参数1,参数2)
功能:比较参数1和参数(1、若参数1>参数2,返回正数;2、若参数1<参数2,返回负数;3、若参数1=参数2,返回0;)

基于OpenNI接口的点云数据获取
代码:

 #include <pcl/io/openni_grabber.h> 
 #include <pcl/visualization/cloud_viewer.h> 

 class SimpleOpenNIViewer
 {
   public:
     SimpleOpenNIViewer () : viewer ("PCL OpenNI Viewer") {}//定义一个显示界面
     //定义回调函数cloud_cb_,获取到数据时对数据进行处理
     void cloud_cb_ (const pcl::PointCloud<pcl::PointXYZ>::ConstPtr &cloud)
     {
       if (!viewer.wasStopped())
       //有输入时就显示
         viewer.showCloud (cloud);
     }

     void run ()
     {
       //为openni的设备创建一个新的grabber
       pcl::Grabber* interface = new pcl::OpenNIGrabber();
       //使得回调函数来自于成员函数
       boost::function<void (const pcl::PointCloud<pcl::PointXYZ>::ConstPtr&)> f =
         boost::bind (&SimpleOpenNIViewer::cloud_cb_, this, _1);
       //对期望信号连接回调函数
       interface->registerCallback (f);
       //接收点云信息
       interface->start ();

       while (!viewer.wasStopped())
       {
         boost::this_thread::sleep (boost::posix_time::seconds (1));
       }
       //停止数据采集
       interface->stop ();
     }

     pcl::visualization::CloudViewer viewer;
 };

 int main ()
 {
   SimpleOpenNIViewer v;
   v.run ();
   return 0;
 }

boost::bind详细解释:

bind()是一个函数模板,它的原理是根据已有的模板,生成一个函数

 boost::function<void (const pcl::PointCloud<pcl::PointXYZ>::ConstPtr&)> f =
         boost::bind (&SimpleOpenNIViewer::cloud_cb_, this, _1);

此处 f 就是实例化的模板函数,此类型的函数对象可以在OpenNIGrabber中注册

1.绑定参数,如:
bind(f, 1, 2)等价于f(1, 2); bind(g, 1, 2, 3)等价于g(1, 2, 3);
也可以选择性地绑定参数,如:
bind(f, _1, 5)(x)等价于f(x, 5),其中_1是一个占位符,表示第一个参数来替换;
bind(f, _2, _1)(x, y)等价于f(y, x);
bind(g, _1, 9, _1)(x)等价于g(x, 9, x);
bind(g, _3, _3, _3)(x, y, z)等价于g(z, z, z);

2.例:

struct X
  {
      bool f(int a);
  };
  
  X x;
  shared_ptr<X> p(new X);
  int i = 5;
  
 bind(&X::f, ref(x), _1)(i);        // x.f(i)
 bind(&X::f, &x, _1)(i);            // (&x)->f(i)
 bind(&X::f, x, _1)(i);            // x.f(i)
 bind(&X::f, p, _1)(i);            // p->f(i)

关于std::ref和std::cref:

#include <functional>
#include <iostream>

void f(int& n1, int& n2, const int& n3)
{
    std::cout << "In function: n1[" << n1 << "]    n2[" << n2 << "]    n3[" << n3 << "]" << std::endl;
    ++n1; // 增加存储于函数对象的 n1 副本
    ++n2; // 增加 main() 的 n2
    //++n3; // 编译错误
    std::cout << "In function end: n1[" << n1 << "]     n2[" << n2 << "]     n3[" << n3 << "]" << std::endl;
}

int main()
{
    int n1 = 1, n2 = 1, n3 = 1;
    std::cout << "Before function: n1[" << n1 << "]     n2[" << n2 << "]     n3[" << n3 << "]" << std::endl;
    std::function<void()> bound_f = std::bind(f, n1, std::ref(n2), std::cref(n3));
    bound_f();
    std::cout << "After function: n1[" << n1 << "]     n2[" << n2 << "]     n3[" << n3 << "]" << std::endl;
}

运行结果:

Before function: n1[1]     n2[1]     n3[1]
In function: n1[1]    n2[1]    n3[1]
In function end: n1[2]     n2[2]     n3[1]
After function: n1[1]     n2[2]     n3[1]

分析:
n1是值传递,函数内部的修改对外面没有影响。
n2是引用传递,函数内部的修改影响外面。
n3是const引用传递,函数内部不能修改。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值