Semana 4 - Visor 3D para secuencias LiDAR
Esta semana me he enfocado exclusivamente en mejorar el Visor 3D, con el objetivo de permitir la visualización de secuencias de muestras. Continué trabajando con la librería de visualización 3D que ya estaba utilizando junto con Dash, pero me encontré con una limitación: la tasa máxima de muestras por segundo que soporta no es suficiente para la aplicación final del visor
Por ello, comencé a explorar alternativas y encontré la solución con Open3D, una biblioteca que ofrece mejores resultados porque funciona directamente con la tarjeta gráfica, lo que reduce la carga computacional y mejora significativamente la tasa de muestras por segundo
Visualizador 3D de secuencias con Open3d
Código Principal
El programa principal se encuentra en el archivo main.py
. Aquí se detallan algunos aspectos clave de su funcionamiento:
-
Lectura de archivos LiDAR: Se utiliza la función
leer_archivos_lidar
para leer los archivos.bin
que contienen los puntos 3D y sus remisiones (intensidades). Este proceso es asíncrono, lo que permite cargar múltiples archivos de forma eficiente. -
Visualización 3D: La función
visualizar_nube_puntos
utiliza Open3D para mostrar la nube de puntos, añadiendo también elementos adicionales como ejes de coordenadas y una representación del sensor LiDAR. Además, permite cambiar el colormap utilizando la libreríamatplotlib
para mejorar la interpretación visual. -
Interacción del Usuario: Se han configurado callbacks que permiten navegar entre los diferentes archivos LiDAR, avanzando o retrocediendo con las flechas del teclado. También es posible alternar entre diferentes mapas de colores para visualizar las remisiones y activar una vista reducida que muestra solo un subconjunto de puntos para mejorar el rendimiento.
A continuación muestro el fragmento clave del código de visualización:
def visualizar_nube_puntos(puntos, remisiones, vis):
# Verificar si la nube de puntos está vacía
if len(puntos) == 0:
print("[Advertencia] La nube de puntos está vacía, omitiendo visualización.")
return
# Crear la nube de puntos si tiene datos
nube_puntos = o3d.geometry.PointCloud()
nube_puntos.points = o3d.utility.Vector3dVector(puntos)
# Normalizar las remisiones a un rango de 0 a 1
remisiones_normalizadas = np.asarray(remisiones)
remisiones_normalizadas = (remisiones_normalizadas - remisiones_normalizadas.min()) / (remisiones_normalizadas.max() - remisiones_normalizadas.min())
# Crear un mapa de color lineal usando matplotlib basado en el colormap actual
cmap = plt.get_cmap(colormaps[colormap_idx[0]]) # Mapa de colores actual
colores = cmap(remisiones_normalizadas)[:, :3] # Obtener solo el canal RGB
# Asignar los colores a la nube de puntos
nube_puntos.colors = o3d.utility.Vector3dVector(colores)
# Limpiar geometrías previas
vis.clear_geometries()
# Añadir la nueva nube de puntos
vis.add_geometry(nube_puntos)
...
Consideraciones Futuras
Por el momento, esta es una primera versión funcional del visor 3D. Si bien cumple con los requisitos básicos de visualización, tendré que realizar una reestructuración del código para mejorar su rendimiento y flexibilidad para otras fuentes de datos, ya sean simulados en tiempo real o de otras bases de datos