split some code into functions point_radius=40,
Browse filesmax_angle=15,
extend=25,
merge_th=80.0,
min_missing_distance=500.0,
scale_estimation_coefficient=2.54,
clustering_eps=120,
interpolation_radius=10000,
point_radius_scale=0.5,
# dist_coeff=0,
pointcloud_depth_coeff=1.005,
- handcrafted_solution.py +61 -62
- script.py +2 -2
handcrafted_solution.py
CHANGED
|
@@ -505,49 +505,83 @@ def prune_not_connected(all_3d_vertices, connections_3d):
|
|
| 505 |
|
| 506 |
return np.array(new_verts), connected_out
|
| 507 |
|
| 508 |
-
|
| 509 |
-
def predict(entry, visualize=False,
|
| 510 |
-
scale_estimation_coefficient=2.5,
|
| 511 |
-
clustering_eps=100,
|
| 512 |
-
dist_coeff=0,
|
| 513 |
-
pointcloud_depth_coeff = 1,
|
| 514 |
-
interpolation_radius=200,
|
| 515 |
-
**kwargs) -> Tuple[np.ndarray, List[int]]:
|
| 516 |
-
if 'gestalt' not in entry or 'depthcm' not in entry or 'K' not in entry or 'R' not in entry or 't' not in entry:
|
| 517 |
-
print('Missing required fields in the entry')
|
| 518 |
-
return (entry['__key__'], *empty_solution())
|
| 519 |
-
entry = hoho.decode(entry)
|
| 520 |
-
|
| 521 |
-
vert_edge_per_image = {}
|
| 522 |
image_dict = {}
|
| 523 |
for k, v in entry["images"].items():
|
| 524 |
image_dict[v.name] = v
|
| 525 |
points = [v.xyz for k, v in entry["points3d"].items()]
|
| 526 |
-
|
| 527 |
points = np.array(points)
|
| 528 |
point_keys = [k for k, v in entry["points3d"].items()]
|
| 529 |
point_keys = np.array(point_keys)
|
| 530 |
-
|
| 531 |
# print(len(points))
|
| 532 |
-
|
| 533 |
clustered = DBSCAN(eps=clustering_eps, min_samples=10).fit(points).labels_
|
| 534 |
clustered_indices = np.argsort(clustered)
|
| 535 |
-
|
| 536 |
points = points[clustered_indices]
|
| 537 |
point_keys = point_keys[clustered_indices]
|
| 538 |
clustered = clustered[clustered_indices]
|
| 539 |
-
|
| 540 |
_, cluster_indices = np.unique(clustered, return_index=True)
|
| 541 |
-
|
| 542 |
clustered_points = np.split(points, cluster_indices[1:])
|
| 543 |
clustered_keys = np.split(point_keys, cluster_indices[1:])
|
| 544 |
-
|
| 545 |
biggest_cluster_index = np.argmax([len(i) for i in clustered_points])
|
| 546 |
biggest_cluster = clustered_points[biggest_cluster_index]
|
| 547 |
biggest_cluster_keys = clustered_keys[biggest_cluster_index]
|
| 548 |
biggest_cluster_keys = set(biggest_cluster_keys)
|
| 549 |
-
|
| 550 |
points3d_kdtree = KDTree(biggest_cluster)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 551 |
|
| 552 |
|
| 553 |
for i, (gest, depthcm, K, R, t, imagekey) in enumerate(zip(entry['gestalt'],
|
|
@@ -569,56 +603,25 @@ def predict(entry, visualize=False,
|
|
| 569 |
depth_np = np.array(depthcm) / scale_estimation_coefficient
|
| 570 |
uv, depth_vert_from_depth_map = get_uv_depth(vertices, depth_np)
|
| 571 |
try:
|
| 572 |
-
|
| 573 |
-
|
| 574 |
-
|
| 575 |
-
for idx, point_id in zip(point_indices, image_dict[imagekey].point3D_ids[point_indices]):
|
| 576 |
-
if point_id in biggest_cluster_keys:
|
| 577 |
-
belonging_points3d.append(entry["points3d"][point_id].xyz)
|
| 578 |
-
belonging_points2d.append(image_dict[imagekey].xys[idx])
|
| 579 |
-
|
| 580 |
-
if len(belonging_points3d) < 1:
|
| 581 |
-
print(f'No 3D points in image {i}')
|
| 582 |
-
vert_edge_per_image[i] = np.empty((0, 2)), [], np.empty((0, 3))
|
| 583 |
-
raise KeyError
|
| 584 |
-
belonging_points3d = np.array(belonging_points3d)
|
| 585 |
-
belonging_points2d = np.array(belonging_points2d)
|
| 586 |
-
# projected2d, _ = cv2.projectPoints(belonging_points3d, R, t, K, dist_coeff)
|
| 587 |
-
important = np.where(np.all(belonging_points2d >= 0, axis=1))
|
| 588 |
-
# Normalize the uv to the camera intrinsics
|
| 589 |
-
world_to_cam = np.eye(4)
|
| 590 |
-
world_to_cam[:3, :3] = R
|
| 591 |
-
world_to_cam[:3, 3] = t
|
| 592 |
-
|
| 593 |
-
homo_belonging_points = cv2.convertPointsToHomogeneous(belonging_points3d)
|
| 594 |
-
depth = cv2.convertPointsFromHomogeneous(cv2.transform(homo_belonging_points, world_to_cam))
|
| 595 |
-
depth = depth[:, 0, 2]
|
| 596 |
-
# projected2d = projected2d[:, 0, :]
|
| 597 |
-
depth = depth[important[0]]
|
| 598 |
-
# projected2d = projected2d[important[0]]
|
| 599 |
-
projected2d = belonging_points2d[important[0]]
|
| 600 |
-
# print(projected2d.shape)
|
| 601 |
-
# print(depth.shape)
|
| 602 |
-
depth *= pointcloud_depth_coeff
|
| 603 |
if len(depth) < 1:
|
| 604 |
print(f'No 3D points in image {i}')
|
| 605 |
-
vert_edge_per_image[i] = np.empty((0, 2)), [], np.empty((0, 3))
|
| 606 |
raise KeyError
|
| 607 |
-
|
| 608 |
|
| 609 |
# interpolator = si.NearestNDInterpolator(projected2d, depth, rescale=True)
|
| 610 |
interpolator = NearestNDInterpolatorWithThreshold(projected2d, depth, interpolation_radius)
|
| 611 |
-
# interpolator = si.LinearNDInterpolator(projected2d, depth, np.nan)
|
| 612 |
|
| 613 |
uv = np.array([v['xy'] for v in vertices])
|
| 614 |
xi, yi = uv[:, 0], uv[:, 1]
|
| 615 |
depth_vert_from_pointcloud = interpolator(xi, yi)
|
| 616 |
depthmap_used = False
|
| 617 |
|
| 618 |
-
# Get the 3D vertices
|
| 619 |
except KeyError:
|
| 620 |
#Revert to the depthmap
|
| 621 |
-
# Metric3D
|
| 622 |
depthmap_used = True
|
| 623 |
|
| 624 |
# Normalize the uv to the camera intrinsics
|
|
@@ -630,12 +633,8 @@ def predict(entry, visualize=False,
|
|
| 630 |
|
| 631 |
depth_vert_nan_idxs = None
|
| 632 |
if depthmap_used:
|
| 633 |
-
# norm_factor = np.max(np.linalg.norm(xy_local, axis=1)[..., None])
|
| 634 |
depth_vert = depth_vert_from_depth_map
|
| 635 |
else:
|
| 636 |
-
# 1. query detected vertices in projected2d
|
| 637 |
-
# if the vertex is beyond some radius, use the depthmap
|
| 638 |
-
# isnt uv
|
| 639 |
depth_vert_nan_idxs = np.where(np.isnan(depth_vert_from_pointcloud))[0]
|
| 640 |
depth_vert_from_pointcloud[depth_vert_nan_idxs] = depth_vert_from_depth_map[depth_vert_nan_idxs]
|
| 641 |
depth_vert = depth_vert_from_pointcloud
|
|
|
|
| 505 |
|
| 506 |
return np.array(new_verts), connected_out
|
| 507 |
|
| 508 |
+
def clean_points3d(entry, clustering_eps):
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 509 |
image_dict = {}
|
| 510 |
for k, v in entry["images"].items():
|
| 511 |
image_dict[v.name] = v
|
| 512 |
points = [v.xyz for k, v in entry["points3d"].items()]
|
| 513 |
+
|
| 514 |
points = np.array(points)
|
| 515 |
point_keys = [k for k, v in entry["points3d"].items()]
|
| 516 |
point_keys = np.array(point_keys)
|
| 517 |
+
|
| 518 |
# print(len(points))
|
| 519 |
+
|
| 520 |
clustered = DBSCAN(eps=clustering_eps, min_samples=10).fit(points).labels_
|
| 521 |
clustered_indices = np.argsort(clustered)
|
| 522 |
+
|
| 523 |
points = points[clustered_indices]
|
| 524 |
point_keys = point_keys[clustered_indices]
|
| 525 |
clustered = clustered[clustered_indices]
|
| 526 |
+
|
| 527 |
_, cluster_indices = np.unique(clustered, return_index=True)
|
| 528 |
+
|
| 529 |
clustered_points = np.split(points, cluster_indices[1:])
|
| 530 |
clustered_keys = np.split(point_keys, cluster_indices[1:])
|
| 531 |
+
|
| 532 |
biggest_cluster_index = np.argmax([len(i) for i in clustered_points])
|
| 533 |
biggest_cluster = clustered_points[biggest_cluster_index]
|
| 534 |
biggest_cluster_keys = clustered_keys[biggest_cluster_index]
|
| 535 |
biggest_cluster_keys = set(biggest_cluster_keys)
|
| 536 |
+
|
| 537 |
points3d_kdtree = KDTree(biggest_cluster)
|
| 538 |
+
|
| 539 |
+
return points3d_kdtree, biggest_cluster_keys, image_dict
|
| 540 |
+
|
| 541 |
+
def get_depthmap_from_pointcloud(image, pointcloud, biggest_cluster_keys, R, t):
|
| 542 |
+
belonging_points3d = []
|
| 543 |
+
belonging_points2d = []
|
| 544 |
+
point_indices = np.where(image.point3D_ids != -1)[0]
|
| 545 |
+
for idx, point_id in zip(point_indices, image.point3D_ids[point_indices]):
|
| 546 |
+
if point_id in biggest_cluster_keys:
|
| 547 |
+
belonging_points3d.append(pointcloud[point_id].xyz)
|
| 548 |
+
belonging_points2d.append(image.xys[idx])
|
| 549 |
+
|
| 550 |
+
if len(belonging_points3d) < 1:
|
| 551 |
+
print(f'No 3D points in image {image.name}')
|
| 552 |
+
raise KeyError
|
| 553 |
+
belonging_points3d = np.array(belonging_points3d)
|
| 554 |
+
belonging_points2d = np.array(belonging_points2d)
|
| 555 |
+
# projected2d, _ = cv2.projectPoints(belonging_points3d, R, t, K, dist_coeff)
|
| 556 |
+
important = np.where(np.all(belonging_points2d >= 0, axis=1))
|
| 557 |
+
# Normalize the uv to the camera intrinsics
|
| 558 |
+
world_to_cam = np.eye(4)
|
| 559 |
+
world_to_cam[:3, :3] = R
|
| 560 |
+
world_to_cam[:3, 3] = t
|
| 561 |
+
|
| 562 |
+
homo_belonging_points = cv2.convertPointsToHomogeneous(belonging_points3d)
|
| 563 |
+
depth = cv2.convertPointsFromHomogeneous(cv2.transform(homo_belonging_points, world_to_cam))
|
| 564 |
+
depth = depth[:, 0, 2]
|
| 565 |
+
# projected2d = projected2d[:, 0, :]
|
| 566 |
+
depth = depth[important[0]]
|
| 567 |
+
# projected2d = projected2d[important[0]]
|
| 568 |
+
projected2d = belonging_points2d[important[0]]
|
| 569 |
+
return projected2d, depth
|
| 570 |
+
def predict(entry, visualize=False,
|
| 571 |
+
scale_estimation_coefficient=2.5,
|
| 572 |
+
clustering_eps=100,
|
| 573 |
+
dist_coeff=0,
|
| 574 |
+
pointcloud_depth_coeff = 1,
|
| 575 |
+
interpolation_radius=200,
|
| 576 |
+
**kwargs) -> Tuple[np.ndarray, List[int]]:
|
| 577 |
+
if 'gestalt' not in entry or 'depthcm' not in entry or 'K' not in entry or 'R' not in entry or 't' not in entry:
|
| 578 |
+
print('Missing required fields in the entry')
|
| 579 |
+
return (entry['__key__'], *empty_solution())
|
| 580 |
+
entry = hoho.decode(entry)
|
| 581 |
+
|
| 582 |
+
vert_edge_per_image = {}
|
| 583 |
+
|
| 584 |
+
points3d_kdtree, biggest_cluster_keys, image_dict = clean_points3d(entry, clustering_eps)
|
| 585 |
|
| 586 |
|
| 587 |
for i, (gest, depthcm, K, R, t, imagekey) in enumerate(zip(entry['gestalt'],
|
|
|
|
| 603 |
depth_np = np.array(depthcm) / scale_estimation_coefficient
|
| 604 |
uv, depth_vert_from_depth_map = get_uv_depth(vertices, depth_np)
|
| 605 |
try:
|
| 606 |
+
image = image_dict[imagekey]
|
| 607 |
+
|
| 608 |
+
projected2d, depth = get_depthmap_from_pointcloud(image, entry["points3d"], biggest_cluster_keys, R, t)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 609 |
if len(depth) < 1:
|
| 610 |
print(f'No 3D points in image {i}')
|
| 611 |
+
# vert_edge_per_image[i] = np.empty((0, 2)), [], np.empty((0, 3))
|
| 612 |
raise KeyError
|
| 613 |
+
depth *= pointcloud_depth_coeff
|
| 614 |
|
| 615 |
# interpolator = si.NearestNDInterpolator(projected2d, depth, rescale=True)
|
| 616 |
interpolator = NearestNDInterpolatorWithThreshold(projected2d, depth, interpolation_radius)
|
|
|
|
| 617 |
|
| 618 |
uv = np.array([v['xy'] for v in vertices])
|
| 619 |
xi, yi = uv[:, 0], uv[:, 1]
|
| 620 |
depth_vert_from_pointcloud = interpolator(xi, yi)
|
| 621 |
depthmap_used = False
|
| 622 |
|
|
|
|
| 623 |
except KeyError:
|
| 624 |
#Revert to the depthmap
|
|
|
|
| 625 |
depthmap_used = True
|
| 626 |
|
| 627 |
# Normalize the uv to the camera intrinsics
|
|
|
|
| 633 |
|
| 634 |
depth_vert_nan_idxs = None
|
| 635 |
if depthmap_used:
|
|
|
|
| 636 |
depth_vert = depth_vert_from_depth_map
|
| 637 |
else:
|
|
|
|
|
|
|
|
|
|
| 638 |
depth_vert_nan_idxs = np.where(np.isnan(depth_vert_from_pointcloud))[0]
|
| 639 |
depth_vert_from_pointcloud[depth_vert_nan_idxs] = depth_vert_from_depth_map[depth_vert_nan_idxs]
|
| 640 |
depth_vert = depth_vert_from_pointcloud
|
script.py
CHANGED
|
@@ -146,13 +146,13 @@ if __name__ == "__main__":
|
|
| 146 |
max_angle=15,
|
| 147 |
extend=25,
|
| 148 |
merge_th=80.0,
|
| 149 |
-
min_missing_distance=
|
| 150 |
scale_estimation_coefficient=2.54,
|
| 151 |
clustering_eps=120,
|
| 152 |
interpolation_radius=10000,
|
| 153 |
point_radius_scale=0.5,
|
| 154 |
# dist_coeff=0,
|
| 155 |
-
|
| 156 |
))
|
| 157 |
|
| 158 |
for result in tqdm(results, desc='Results', total=len(results), position=0):
|
|
|
|
| 146 |
max_angle=15,
|
| 147 |
extend=25,
|
| 148 |
merge_th=80.0,
|
| 149 |
+
min_missing_distance=500.0,
|
| 150 |
scale_estimation_coefficient=2.54,
|
| 151 |
clustering_eps=120,
|
| 152 |
interpolation_radius=10000,
|
| 153 |
point_radius_scale=0.5,
|
| 154 |
# dist_coeff=0,
|
| 155 |
+
pointcloud_depth_coeff=1.005,
|
| 156 |
))
|
| 157 |
|
| 158 |
for result in tqdm(results, desc='Results', total=len(results), position=0):
|