从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引用传递,函数内部不能修改。