2 minute read

El trabajo de esta semana ha sido buscar la forma de densificar las nubes de puntos de los datasets Goose y Rellis 3d.

He implementado un programa el cual lee los archivos, .bin o .ply, de un directorio, y crea nubes de puntos densificadas, en el mismo formato que el archivo de entrada. El programa cuenta con una interfaz gráfica que permite seleccionar los directorios de origen y de destino.

infaceDens

La densificación se realiza mediante la funcion densify_point_cloud().

def densify_point_cloud(points: np.ndarray, remissions: np.ndarray, 
                         density_factor: float = 5.0, noise_stddev: float = 0.02) -> tuple[np.ndarray, np.ndarray, np.ndarray, np.ndarray]:
    """
    Densifica la nube de puntos sin perder detalle, añadiendo puntos de forma controlada.
    """
    num_new_points = int(len(points) * density_factor)
    
    # Seleccionar índices aleatorios para añadir puntos
    base_indices = np.random.choice(len(points), num_new_points, replace=True)
    
    # Añadir ruido controlado a los puntos seleccionados
    noise_points = points[base_indices] + np.random.normal(0, noise_stddev, (num_new_points, 3))
    
    # Las intensidades de los nuevos puntos son las mismas que las de los puntos seleccionados
    noise_remissions = remissions[base_indices]
    
    return points, remissions, noise_points, noise_remissions

La funcion selecciona puntos de la nube original de manera aleatoria y les agrega un poco de ruido, generando nuevos puntos cerca de los puntos originales. Consigueinso una nube más densa.

density_factor: Contola cuantos puntos adicionales se generan por punto original.

noise_stddev: Establece la cantidad de cariacion que se agrega a los nuevos puntos.

densRuido

También he realizar una densificación por interpolación de vecinos. Este metodo tiene el problema de que el tiempo que necesita para el cálculo es demasiado alto.

en este caso la densificación se realiza con la función densify_point_cloud() pero en este caso es de la siguiente forma:

```python def densify_point_cloud(points: np.ndarray, remissions: np.ndarray, density_factor: float = 5.0, n_neighbors: int = 5) -> Tuple[np.ndarray, np.ndarray, np.ndarray, np.ndarray]: “”” Densifica la nube de puntos utilizando interpolación basada en vecinos más cercanos.

:param points: Nube de puntos original (N, 3)
:param remissions: Intensidades de los puntos originales (N,)
:param density_factor: Factor de densificación (número de nuevos puntos a agregar)
:param n_neighbors: Número de vecinos cercanos para interpolación
:return: Nuevos puntos generados, sus intensidades, y los puntos originales
"""
# Usar NearestNeighbors para encontrar los vecinos más cercanos
nn = NearestNeighbors(n_neighbors=n_neighbors)
nn.fit(points)

# Establecer el número de nuevos puntos a crear
num_new_points = int(len(points) * density_factor)

# Almacenar los puntos y las intensidades generadas
new_points = []
new_remissions = []

for _ in range(num_new_points):
    # Elegir un punto aleatorio de la nube de puntos original
    index = np.random.randint(0, len(points))
    point = points[index]
    
    # Obtener los vecinos más cercanos
    distances, indices = nn.kneighbors([point], n_neighbors=n_neighbors)
    
    # Seleccionar un vecino aleatorio entre los más cercanos para interpolar
    neighbor_idx = np.random.choice(indices[0])
    neighbor_point = points[neighbor_idx]
    
    # Interpolar entre el punto original y el vecino seleccionado
    interpolated_point = (point + neighbor_point) / 2  # Promedio de la posición
    
    # Las intensidades de los nuevos puntos serán las medias de las intensidades de los puntos vecinos
    interpolated_remission = np.mean(remissions[indices[0]])
    
    # Agregar el nuevo punto y su intensidad
    new_points.append(interpolated_point)
    new_remissions.append(interpolated_remission)

# Convertir las listas a arrays
new_points = np.array(new_points)
new_remissions = np.array(new_remissions)

# Retornar los puntos originales junto con los nuevos puntos
return points, remissions, new_points, new_remissions
```
densVecinos