2 minute read

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

Visor 3D

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ía matplotlib 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