| import numpy as np
|
|
|
|
|
| def evaluate_uniformity_nnd(points):
|
| """
|
| Evaluate point cloud uniformity using Nearest Neighbor Distance (NND)
|
| Args:
|
| points: numpy array of shape (N, 3)
|
| Returns:
|
| dict containing NND statistics
|
| """
|
|
|
| diff = points[:, None, :] - points[None, :, :]
|
| distances = np.sqrt(np.sum(diff * diff, axis=-1))
|
|
|
|
|
| np.fill_diagonal(distances, np.inf)
|
|
|
|
|
| min_distances = np.min(distances, axis=1)
|
|
|
|
|
| metrics = {
|
| 'mean_nnd': np.mean(min_distances),
|
| 'std_nnd' : np.std(min_distances),
|
| 'cv_nnd' : np.std(min_distances) / np.mean(min_distances),
|
| 'min_nnd' : np.min(min_distances),
|
| 'max_nnd' : np.max(min_distances),
|
|
|
|
|
|
|
| 'density' : len(points) / np.prod(np.max(points, axis=0) - np.min(points, axis=0)),
|
| }
|
|
|
|
|
| expected_mean_dist = 0.5 / np.sqrt(metrics['density'])
|
| metrics['clark_evans_r'] = metrics['mean_nnd'] / expected_mean_dist
|
|
|
|
|
| hist, bins = np.histogram(min_distances, bins='auto', density=True)
|
| metrics['hist_values'] = hist
|
| metrics['hist_bins'] = bins
|
|
|
| return metrics
|
|
|