jueves, 12 de diciembre de 2013

Tutorial para generar y visualizar una nube de puntos

En este tutorial explicaremos las diferentes posibilidades para generar un archivo en el que tengamos una nube de puntos.

Como se ha explicado en artículos anteriores, la librería trabaja con un formato de extensión ".pcd". Para poder generar un archivo de este tipo tenemos dos posibilidades :

-Algoritmo: realizando un código mediante el cual se generen puntos que luego serán guardados en un archivo con la extensión. 

-Captura: mediante un dispositivo de captura de imágenes 3D, podemos tomar una nube de puntos y luego guardarlos en un archivo.Este método lo desarrollaremos en otra publicación.

Mediante algoritmo

 En este apartado vamos a realizar un código en el cual generamos puntos de forma aleatoria. el código se muestra a continuación:

#include <iostream>
#include <pcl/io/pcd_io.h>
#include <pcl/point_types.h>
#include <cmath>
#include <cstring>
#include <pcl/visualization/cloud_viewer.h>
#include <pcl/visualization/pcl_visualizer.h>

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

  cloud->width    = 40;
  cloud->height   = 1;
  cloud->is_dense = false;
  cloud->points.resize (cloud->width * cloud->height);
      
   for (i = 0; i < 39; ++i)
          {
            cloud->points[i].x = (1024 * rand () / (RAND_MAX + 1.0f));

            cloud->points[i].y =  (1024 * rand () / (RAND_MAX + 1.0f));
            cloud->points[i].z  =(1024 * rand () / (RAND_MAX + 1.0f));
         }
//  guardar los puntos en el archivo
  pcl::io::savePCDFileASCII ("archivo.pcd", *cloud);
  std::cerr << "Saved " << cloud->points.size () << " data points to archivo.pcd." << std::endl;
//visualizar la nube de puntos
 pcl::visualization::CloudViewer viewer("Cloud Viewer");
  viewer.showCloud(cloud);
  while (!viewer.wasStopped ())
    {
    }
 return (0);
}


Para iniciar el código debemos de indicar las librerías que utilizaran las funciones de nuestro código, en nuestro caso tenemos los siguientes includes:

#include <iostream> 
B0ásico para trabajar en C++.

#include <pcl/io/pcd_io.h>
 Esta librería se encarga de la escritura, apertura y lectura de archivos de extensión pcd.

#include <pcl/point_types.h>
 Esta librería nos permite utilizar los tipos de datos que se utilizan en PCL evitando la tediosa tarea de asignar memoria para cada tipo de dato.

#include <cmath>
Esta biblioteca es básica en C++ y la utilizamos para la función en la que pedimos numeros aleatorios.

#include <cstring>

En esta biblioteca se incluyen rutinas de manipulación de cadenas de caracteres y de memoria.


#include <pcl/visualization/cloud_viewer.h>

#include <pcl/visualization/pcl_visualizer.h>

Esta librerías nos permiten visualizar las nubes de puntos.

Luego en el cuerpo principal, lo primero que se debe hacer es introducir las zonas de memoria, en nuestros caso solo necesitamos un entero y un puntero para nube de puntos de la siguiente manera:

pcl::PointCloud<pcl::PointXYZRGB>::Ptr cloud  (new pcl::PointCloud<pcl::PointXYZRGB>);

 Como podemos ver es un puntero en el cual podemos hacer una nube de puntos con coordenadas en los ejes cartesianos, y componentes de color rojo(R), verde(G) y azul(B).

Una vez asignada la zona de memoria de la nube, debemos de dar las dimensiones que deseamos que tenga la nube de puntos, como es un ejemplo hemos dado dimensiones pequeñas, aunque puede llegar a tener millones de puntos.El fragmento que exponemos es imprescindible si  creamos nosotros la nube, no así si la leemos, por lo que tenemos:

  cloud->width    = 40;
  cloud->height   = 1;
  cloud->is_dense = false;
  cloud->points.resize (cloud->width * cloud->height);


Luego simplemente tenemos que generar una serie de puntos de forma aleatoria, aunque también podríamos hacerlo de forma ordenada y consiguiendo planos, o diferentes formas geometrías. Para generar los puntos de forma aleatoria lo hemos realizado de la siguiente manera:

  for (i = 0; i < 39; ++i)
          {
            cloud->points[i].x = (1024 * rand () / (RAND_MAX + 1.0f));

            cloud->points[i].y =  (1024 * rand () / (RAND_MAX + 1.0f));
            cloud->points[i].z  =(1024 * rand () / (RAND_MAX + 1.0f));
         }


Una vez creada la nube de puntos podemos guardarla en un archivo .pcd, en formato binario o ASCII, nosotros lo tenemos en el código como ASCII, la forma de guardarlo seria:

-Código ASCII: pcl::io::savePCDFileASCII ("archivo.pcd", *cloud);
-Binario: pcl::io::savePCDFileBinary ("test_pcd4.pcd", *cloud);

 También podemos visualizar nube de puntos, hemos utilizado el siguiente código que entra en un bucle infinito.

 pcl::visualization::CloudViewer viewer("Cloud Viewer");
  viewer.showCloud(cloud);
  while (!viewer.wasStopped ())
    {
    }


Para visualizar un archivo pcd también lo podemos hacer mediante consola con el siguiente comando:

$pcd_viewer archivo.pcd



nota: para ver los puntos mas grandes pulsar la tecla de (+)


 

No hay comentarios:

Publicar un comentario