Semanas 6 y 7 - Primera versión del Visor LiDAR, Exploración de Segmentación por Parches Planos
Durante las últimas dos semanas, me he dedicado a formalizar la primera versión del LiDAR-Visualizer
. Para ello, he unificado las diferentes ramas de desarrollo para cada fuente de datos reestructurando el código base y añadí diversas mejoras, como una interfaz inicial que permite seleccionar el modo de ejecución (Ficheros, CARLA). También incorporé funcionalidades adicionales, entre ellas, el control mediante teclas para alternar entre los modos automático y manual, ajuste de los FPS en modo automático, cambio del colormap, modificación del color de fondo, remuestreo para optimizar la renderización y la opción de cambiar de cámara con dos configuraciones posibles. Finalmente, comencé a investigar la segmentación por parches planos y realicé una prueba de segmentación del suelo.
Reestructuración del Código
Esta es la nueva estructura para la primera versión del programa:
Lidar-Visualizer
│
├── src
│ ├── gui
│ │ └── gui.py
│ │
│ ├── lidar_visualization
│ │ ├── carla_viz.py
│ │ └── file_viz.py
│ │
│ └── main.py
│
├── data
│ └── examples
│ ├── goose
│ │ └── muestras de ejemplo
│ │
│ └── rellis
│ └── muestras de ejemplo
│
├── README.md
└── setup.py
Ejemplos de Ejecución del Visor 3D
Ejecución a partir de archivos de bases de datos
Ejecución a partir de un sensor LiDAR simulado en CARLA en tiempo real
Segmentación por Parches Planos con el Algoritmo RANSAC
Dado el soporte limitado de la biblioteca PCL en Python, he estado explorando los métodos de Open3D para la segmentación. En particular, Open3D ofrece una implementación del algoritmo RANSAC. En el siguiente código se busca la segmentación del suelo en la muestra LiDAR:
pcd = o3d.geometry.PointCloud()
pcd.points = o3d.utility.Vector3dVector(nube_puntos)
plane_model, inliers = pcd.segment_plane(distance_threshold=0.2, ransac_n=3, num_iterations=1000)
[a, b, c, d] = plane_model
print(f"Plano del suelo: {a:.2f}x + {b:.2f}y + {c:.2f}z + {d:.2f} = 0")
suelo_cloud = pcd.select_by_index(inliers)
Resultado
Funcionamiento
- Selección Aleatoria y Modelo de Plano:
- RANSAC selecciona aleatoriamente tres puntos de la nube y calcula un plano que pase por ellos. Con tres puntos es posible definir un único plano en el espacio tridimensional.
- Criterio de Pertenencia (Inliers):
- Para cada plano propuesto, RANSAC evalúa qué puntos de la nube están cerca de este plano, utilizando un umbral de distancia
distance_threshold = 0.2
. Los puntos que están dentro de este límite se consideran inliers.
- Para cada plano propuesto, RANSAC evalúa qué puntos de la nube están cerca de este plano, utilizando un umbral de distancia
- Iteración y Selección del Mejor Modelo:
- Este proceso se repite durante un número determinado de iteraciones
num_iterations = 1000
. En cada iteración, RANSAC busca maximizar el número de inliers. Al final, selecciona el plano que tiene el mayor número de inliers como el plano óptimo.
- Este proceso se repite durante un número determinado de iteraciones
- Resultado:
- RANSAC devuelve dos resultados clave:
plane_model
: Los coeficientes[a, b, c, d]
que definen el plano en la ecuaciónax + by + cz + d = 0
.inliers
: Los índices de los puntos que forman parte del plano identificado.
- RANSAC devuelve dos resultados clave: