sábado, 1 de marzo de 2014

Filtros



Introducción

El filtrado de imágenes es tal vez una de las operaciones mas importantes en el procesamiento de imágenes. Debido a los errores de medición, las nubes de puntos presentan un gran número de puntos de sombra. Esto complica la estimación de las funciones 3D de nubes de puntos locales. Algunos de estos valores extremos se pueden filtrar mediante la realización de un análisis estadístico en el vecindario de cada punto, y se eliminan los que no cumplen con determinados criterios.
A la hora de implementar un filtro los resultados que deseamos conseguir pueden ser diferentes, y en muchos casos deseamos investigar como trabaja el filtro, para comparar diferentes parámetros que nos servirá para investigar las bondades de cada filtro. En esta librería se encuentran todas las funciones para realizarlo.

Módulo de filtros de PCL

Primero vamos a ver los diferentes tipos de filtros que disponemos y sus características.

tipos de filtros.

Remove NaN from point cloud.

Es una llamada que tiene por objetivo copiar todos los puntos que no están definidos por valores en la nube de entrada(cloud_in) y copiarlos en otra nube de salida(cloud_out), por lo que no elimina todos los valores atípicos pero si aquellos que los son por no estar definidos. La función se muestra:
void pcl::removeNaNFromPointCloud(const pcl::PointCloud< PointT > &cloud_in,pcl::PointCloud< PointT > &cloud_out, std::vector< int > &index)

Donde:
[in] cloud_in la nube de puntos de entrada
[out] cloud_out ella
nube de puntos de salida
[out]index:vector de asignación de índices de entrada:cloud_out.points[i]=cloud_in.points[Índice[i]]

Approximate Voxel Grid.

 Este filtro disminuye la resolución de una nube de puntos ya que divide en cuadriculas(voxel) la nube, filtrando los datos atípicos, también tenemos la posibilidad de restringir las cuadriculas que no tienen un número mínimo de puntos. Cuando se ejecuta este filtro se corrompe la matriz de datos en que son ordenados. La clase:
pcl::ApproximateVoxelGrid< PointT > Class Template Reference

Implementacion sencilla:
pcl::ApproximateVoxelGrid<pcl::PointXYZRGBA> AVG;
//tamaño de cubo= l
AVG.setLeafSize(l,l,l); 
AVG.setMinimumPointsNumberPerVoxel (2);
AVG.setInputCloud(cloud_filtered);
AVG.filter(*cloud);

 Si deseamos restringir la cuadricula con numero mínimo de puntos tenemos la función :
setMinimumPointsNumberPerVoxel (unsigned int puntos_mínimos_por_voxel)

Bilateral Filter.

Es un filtro donde los datos atípicos son corregidos a través de los valores de sus vecinos mas cercanos, bajo la premisa de que la imagen varia lentamente en el espacio. Este filtro no elimina parte de los datos de la nube si no que los modifica, a la vez que mantiene la resolución y la estructura de datos inicial. La clase:
class pcl::BilateralFilter< PointT >

Fragmento del código:

pcl::BilateralFilter<pcl::PointXYZI> BF;
pcl::search::KdTree<pcl::PointXYZI>::Ptr tree (new     pcl::search::KdTree<pcl::PointXYZI>);

BF.setSearchMethod(tree);
BF.setHalfSize(l);//
el tamaño medio de la ventana de filtro bilateral de Gauss para usar.
BF.setStdDev (0.01);//
el nuevo parámetro de desviación estándar.
BF.setInputCloud(cloud_filtered);

BF.filter(*cloud)
;
Debemos observar que este filtro trabaja con valores de intensidad y no de colores RGB, por lo que es necesario modificar la nube si las tenemos con datos que no son del tipo XYZI.



Pass Through.

El objetivo de este filtro no es la eliminación de datos atípicos, aunque aquellos que no tienen valor numérico son descartado. Consiste en filtrar por campo, condicionando para ciertos valores, por ejemplo si queremos que los puntos estén entre , 1m y 2m de distancia sobre la "x", seleccionamos el campo "x" y limitaos los valores. La clase:


class pcl::PassThrough< PointT >

Fragmento del código:
pcl::PassThrough<pcl::PointXYZ> pass;
pass.setInputCloud (cloud);
pass.setFilterFieldName ("z");
pass.setFilterLimits (1.5, 2.50);
pass.filter (*cloud_filtered);


GridMinimum

Este tipo de filtro pretende reducir la resolución de la imagen a través de una cuadricula en 2D, de los datos que están en la celda se seleccionan el que tenga el valor mínimo de la dimensión Z. Este algoritmo que sigue teniendo una base estadística, puede ser mucho más rápido ya que solo centra en labores de comparación, pero perdemos todo el orden original de los datos.Una forma de implementacion podría ser la siguiente:

class pcl::GridMinimum< PointT >

 float l;
 l=5*computeCloudResolution(cloud);
 pcl::GridMinimum <pcl::PointXYZRGBA> GridMini(l);
        GridMini.setResolution(l);
        GridMini.setInputCloud(cloud);
        GridMini.filter(*output);