Spaces:
Running
on
Zero
Running
on
Zero
| import os, sys | |
| sys.path.append(os.path.join(os.path.dirname(__file__), '..', '..')) | |
| import numpy as np | |
| from metrics.iou import ( | |
| _sample_points_in_box3d, | |
| _apply_backward_transformations, | |
| _apply_forward_transformations, | |
| _count_points_in_box3d, | |
| ) | |
| def giou_aabb(bbox1_vertices, bbox2_verices): | |
| """ | |
| Compute the generalized IoU between two axis-aligned bounding boxes\n | |
| - bbox1_vertices: the vertices of the first bounding box in the form: [[x0, y0, z0], [x1, y1, z1], ...]\n | |
| - bbox2_vertices: the vertices of the second bounding box in the form: [[x0, y0, z0], [x1, y1, z1], ...]\n | |
| Return:\n | |
| - giou: the gIoU between the two bounding boxes | |
| """ | |
| volume1 = np.prod(np.max(bbox1_vertices, axis=0) - np.min(bbox1_vertices, axis=0)) | |
| volume2 = np.prod(np.max(bbox2_verices, axis=0) - np.min(bbox2_verices, axis=0)) | |
| # Compute the intersection and union of the two bounding boxes | |
| min_bbox = np.maximum(np.min(bbox1_vertices, axis=0), np.min(bbox2_verices, axis=0)) | |
| max_bbox = np.minimum(np.max(bbox1_vertices, axis=0), np.max(bbox2_verices, axis=0)) | |
| intersection = np.prod(np.clip(max_bbox - min_bbox, a_min=0, a_max=None)) | |
| union = volume1 + volume2 - intersection | |
| # Compute IoU | |
| iou = intersection / union if union > 0 else 0 | |
| # Compute the smallest enclosing box | |
| min_enclosing_bbox = np.minimum(np.min(bbox1_vertices, axis=0), np.min(bbox2_verices, axis=0)) | |
| max_enclosing_bbox = np.maximum(np.max(bbox1_vertices, axis=0), np.max(bbox2_verices, axis=0)) | |
| volume3 = np.prod(max_enclosing_bbox - min_enclosing_bbox) | |
| # Compute gIoU | |
| giou = iou - (volume3 - union) / volume3 if volume3 > 0 else iou | |
| return giou | |
| def sampling_giou( | |
| bbox1_vertices, | |
| bbox2_vertices, | |
| bbox1_transformations, | |
| bbox2_transformations, | |
| num_samples=10000, | |
| ): | |
| """ | |
| Compute the IoU between two bounding boxes\n | |
| - bbox1_vertices: the vertices of the first bounding box\n | |
| - bbox2_vertices: the vertices of the second bounding box\n | |
| - bbox1_transformations: list of transformations applied to the first bounding box\n | |
| - bbox2_transformations: list of transformations applied to the second bounding box\n | |
| - num_samples (optional): the number of samples to use per bounding box\n | |
| Return:\n | |
| - iou: the IoU between the two bounding boxes after applying the transformations | |
| """ | |
| # if no transformations are applied, use the axis-aligned bounding box IoU | |
| if len(bbox1_transformations) == 0 and len(bbox2_transformations) == 0: | |
| return giou_aabb(bbox1_vertices, bbox2_vertices) | |
| # Volume of the two bounding boxes | |
| bbox1_volume = np.prod( | |
| np.max(bbox1_vertices, axis=0) - np.min(bbox1_vertices, axis=0) | |
| ) | |
| bbox2_volume = np.prod( | |
| np.max(bbox2_vertices, axis=0) - np.min(bbox2_vertices, axis=0) | |
| ) | |
| # Volume of the smallest enclosing box | |
| min_enclosing_bbox = np.minimum(np.min(bbox1_vertices, axis=0), np.min(bbox2_vertices, axis=0)) | |
| max_enclosing_bbox = np.maximum(np.max(bbox1_vertices, axis=0), np.max(bbox2_vertices, axis=0)) | |
| cbbox_volume = np.prod(max_enclosing_bbox - min_enclosing_bbox) | |
| # Sample points in the two bounding boxes | |
| bbox1_points = _sample_points_in_box3d(bbox1_vertices, num_samples) | |
| bbox2_points = _sample_points_in_box3d(bbox2_vertices, num_samples) | |
| # Transform the points | |
| forward_bbox1_points = _apply_forward_transformations( | |
| bbox1_points, bbox1_transformations | |
| ) | |
| forward_bbox2_points = _apply_forward_transformations( | |
| bbox2_points, bbox2_transformations | |
| ) | |
| # Transform the forward points to the other box's rest pose frame | |
| forward_bbox1_points_in_rest_bbox2_frame = _apply_backward_transformations( | |
| forward_bbox1_points, bbox2_transformations | |
| ) | |
| forward_bbox2_points_in_rest_bbox1_frame = _apply_backward_transformations( | |
| forward_bbox2_points, bbox1_transformations | |
| ) | |
| # Count the number of points in the other bounding box | |
| num_bbox1_points_in_bbox2 = _count_points_in_box3d( | |
| forward_bbox1_points_in_rest_bbox2_frame, bbox2_vertices | |
| ) | |
| num_bbox2_points_in_bbox1 = _count_points_in_box3d( | |
| forward_bbox2_points_in_rest_bbox1_frame, bbox1_vertices | |
| ) | |
| # Compute the IoU | |
| intersect = ( | |
| bbox1_volume * num_bbox1_points_in_bbox2 | |
| + bbox2_volume * num_bbox2_points_in_bbox1 | |
| ) / 2 | |
| union = bbox1_volume * num_samples + bbox2_volume * num_samples - intersect | |
| iou = intersect / union | |
| giou = iou - (cbbox_volume * num_samples - union) / (cbbox_volume * num_samples) if cbbox_volume > 0 else iou | |
| return giou | |
| def sampling_cDist( | |
| part1, | |
| part2, | |
| bbox1_transformations, | |
| bbox2_transformations, | |
| ): | |
| ''' | |
| Compute the centroid distance between two bounding boxes\n | |
| - bbox1_vertices: the vertices of the first bounding box\n | |
| - bbox2_vertices: the vertices of the second bounding box\n | |
| - bbox1_transformations: list of transformations applied to the first bounding box\n | |
| - bbox2_transformations: list of transformations applied to the second bounding box\n | |
| ''' | |
| bbox1_centroid = np.array(part1['aabb']['center'], dtype=np.float32).reshape(1, 3) | |
| bbox2_centroid = np.array(part2['aabb']['center'], dtype=np.float32).reshape(1, 3) | |
| # Transform the centroids | |
| bbox1_transformed_centroids = _apply_forward_transformations(bbox1_centroid, bbox1_transformations) | |
| bbox2_transformed_centroids = _apply_forward_transformations(bbox2_centroid, bbox2_transformations) | |
| # Compute the centroid distance | |
| cDist = np.linalg.norm(bbox1_transformed_centroids - bbox2_transformed_centroids) | |
| return cDist |