Para empezar es necesario tener un sensor de profundidad en nuestro caso Kinect para Xbox 360, no se ha comprobado si la siguiente versión es compatible. Tener en cuenta que no funciona con los puertos USB 2.0 (vienen con la parte interior en azul).
En el código que mostraremos hay que tener en cuenta que hay una parte que es para la captura y guardado en archivo PCL y otra que es para visualizar la nube capturada.
#include <pcl/io/openni_grabber.h>
#include <pcl/visualization/cloud_viewer.h>
#include <pcl/io/pcd_io.h>
#include <iostream>
#include <fstream>
#include <string.h>
#include <cstring>
#include <sstream>
#include <ctime>
#include <iostream>
#include <locale>
#include <time.h>
#include <stdio.h>
using std::string;
static unsigned int pcd_count = 1;
class SimpleOpenNIViewer{
public:
SimpleOpenNIViewer () : viewer ("PCL OpenNI Viewer") {}
void cloud_cb_ (const pcl::PointCloud<pcl::PointXYZ>::ConstPtr &cloud)
{
std::locale::global(std::locale("es_ES.utf8"));
std::time_t rawtime;
struct tm *timeinfo;
std::time ( &rawtime );
timeinfo = std::localtime ( &rawtime );
char archivo[50] ;
sprintf(archivo, "%d_%d%d%d_%d%d%d_%d",
timeinfo->tm_wday,1900 + timeinfo->tm_year,
timeinfo->tm_mon+1,
timeinfo->tm_mday, timeinfo->tm_hour,
timeinfo->tm_min, timeinfo->tm_sec,pcd_count );
std::strcat(archivo,".pcd");
std::cout<<"estamos en:"<< archivo <<std::endl;
if (!viewer.wasStopped()){
viewer.showCloud (cloud) //guardar archivo
std::cout<<" en archivo"<<archivo <<std::endl;
pcl::io::savePCDFileASCII (archivo, *cloud);
std::cerr << "Saved " << cloud->points.size ()
<< " data points to: "<< archivo << std::endl;
pcd_count++;
boost::this_thread::sleep (boost::posix_time::seconds (3));
}
}
void run ()
{
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;
}
En la clase SimpleOpenNIViewer tenemos dos llamadas la primera que es:
void cloud_cb_
nos servirá para visualizar la nube de puntos y guardarla en una archivo, que en nuestro caso será determinado con fecha y hora ademas de un contador global y la segunda que es:void run ()
Será la llamada que nos permita comunicarnos con el sensor para recibir las nubes de puntos y guardarla en un puntero, y así poderla procesar en la llamada anterior. En esta llamada es importante tener en cuenta que para variar el tiempo entre capturas tendremos que realizarlo en la siguiente líneaboost::this_thread::sleep (boost::posix_time::seconds (tiempo_entre_capturas));
Como ejemplo de nube de puntos mostramos una nube guardada con el nombre 3_2016518_184530_43.pcd