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):
|