1 minute read

Esta semana he estado explorando las opciones que brinda Open3D para procesamiento de nubes de puntos. Ya que los datos que manejamos en este proyecto son muestras LiDAR en exteriores, muchos de los métodos que aplican procesamiento no funcionan correctamente por la variabilidad en la densidad de puntos. En total he extraido 3 métodos que pueden ser de utilidad para el procesamiento o extracción de características de las muestras: planar_patches, clustering, FPFH descriptors

Clustering

Utiliza el algoritmo DBSCAN (Density-Based Spatial Clustering of Applications with Noise) para la segmentación geométrica de objetos en la nube de puntos. Los resultados no son óptimos, pero ajustando bien los parámetros para cada fuente de datos se pueden conseguir resultados decentes. Para mejorar la precisión tengo pensado eliminar antes el suelo con RANSAC para poder ajustar mejor el modelo de segmentación.

Resultado
Visor 3D
Código
labels = np.array(nube_filtrada.cluster_dbscan(eps=0.3, min_points=30, print_progress=True))

# Asignar colores a los clusters
max_label = labels.max()
print(f"Número de clusters encontrados: {max_label + 1}")

colors = plt.get_cmap("tab20")(labels / (max_label if max_label > 0 else 1))
colors[labels < 0] = 0  # Puntos ruidosos sin cluster
nube_filtrada.colors = o3d.utility.Vector3dVector(colors[:, :3])

FPFH

El descriptor FPFH (Fast Point Feature Histogram) describe la forma local alrededor de un punto en la nube de puntos, considerando las relaciones geométricas entre ese punto y sus vecinos. Es un histograma que captura propiedades como las direcciones relativas y distancias entre puntos en un vecindario local

FPFH es una extensión del descriptor PFH (Point Feature Histogram), optimizado para ser más eficiente computacionalmente

Los descriptores FPFH se pueden combinar con algoritmos de clasificación (como SVM, k-NN o redes neuronales) para etiquetar puntos en categorías como planos, bordes o vértices. Pueden ser de gran utilidad

Código
fpfh = o3d.pipelines.registration.compute_fpfh_feature(
    nube,
    search_param=o3d.geometry.KDTreeSearchParamHybrid(radius=0.25, max_nn=100)
)

print(f"Descriptor FPFH calculado: {fpfh.data.shape[1]} descriptores de {fpfh.data.shape[0]} dimensiones cada uno")