Siromanec commited on
Commit
dd68072
1 Parent(s): 25cbb7a

added notebooks

Browse files
.gitattributes CHANGED
@@ -34,3 +34,4 @@ saved_model/**/* filter=lfs diff=lfs merge=lfs -text
34
  *.zst filter=lfs diff=lfs merge=lfs -text
35
  *tfevents* filter=lfs diff=lfs merge=lfs -text
36
  *.whl filter=lfs diff=lfs merge=lfs -text
 
 
34
  *.zst filter=lfs diff=lfs merge=lfs -text
35
  *tfevents* filter=lfs diff=lfs merge=lfs -text
36
  *.whl filter=lfs diff=lfs merge=lfs -text
37
+ *.ipynb filter=lfs diff=lfs merge=lfs -text
examine_results.ipynb ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:a301378de22ca2d5d2798aa02f8380ef75fb75a039d8bcfd7ec64a8f5efe6c0b
3
+ size 3250980
explore.ipynb ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:b8e5020524a5e7fea1d1d97a4a0ed5d2da4fff7ddfd6870a418510018285da0e
3
+ size 86613
handcrafted_solution.py CHANGED
@@ -146,7 +146,12 @@ def get_vertices(image_gestalt, *, color_range=3.5, dialations=2, erosions=1, ke
146
  *_, apex_stats, apex_centroids = cv2.connectedComponentsWithStats(apex_mask, connectivity=4, stats=cv2.CV_32S)
147
  *_, other_stats, other_centroids = cv2.connectedComponentsWithStats(eave_end_point_mask, connectivity=4, stats=cv2.CV_32S)
148
 
149
- return apex_centroids[1:], other_centroids[1:], apex_mask, eave_end_point_mask, apex_stats[1:, cv2.CC_STAT_WIDTH]/2, other_stats[1:, cv2.CC_STAT_WIDTH]/2
 
 
 
 
 
150
 
151
 
152
  def infer_vertices(image_gestalt, *, color_range=4.):
@@ -180,14 +185,14 @@ def get_missed_vertices(vertices, inferred_centroids, *, min_missing_distance=20
180
 
181
 
182
  def get_lines_and_directions(gest_seg_np, edge_class, *, color_range=4., rho, theta, threshold, min_line_length,
183
- max_line_gap, extend, **kwargs):
184
  edge_color = np.array(gestalt_color_mapping[edge_class])
185
 
186
  mask = cv2.inRange(gest_seg_np,
187
  edge_color - color_range,
188
  edge_color + color_range)
189
  mask = cv2.morphologyEx(mask,
190
- cv2.MORPH_DILATE, np.ones((3, 3)), iterations=1)
191
 
192
  if not np.any(mask):
193
  return [], []
@@ -203,20 +208,22 @@ def get_lines_and_directions(gest_seg_np, edge_class, *, color_range=4., rho, th
203
 
204
  line_directions = []
205
  edges = []
 
206
  for line_idx, line in enumerate(lines):
207
  for x1, y1, x2, y2 in line:
208
  if x1 < x2:
209
  x1, y1, x2, y2 = x2, y2, x1, y1
210
  direction = (np.array([x2 - x1, y2 - y1]))
211
  direction = direction / np.linalg.norm(direction)
212
- line_directions.append(direction)
213
 
214
- direction = extend * direction
 
215
 
216
- x1, y1 = -direction + (x1, y1)
217
- x2, y2 = + direction + (x2, y2)
218
 
219
- edges.append((x1, y1, x2, y2))
 
220
  return edges, line_directions
221
 
222
 
@@ -259,7 +266,7 @@ def get_vertices_and_edges_from_segmentation(gest_seg_np, *,
259
 
260
  rho = 1 # distance resolution in pixels of the Hough grid
261
  theta = np.pi / 180 # angular resolution in radians of the Hough grid
262
- threshold = 20 # minimum number of votes (intersections in Hough grid cell)
263
  min_line_length = 60 # minimum number of pixels making up a line
264
  max_line_gap = 40 # maximum gap in pixels between connectable line segments
265
  ridge_edges, ridge_directions = get_lines_and_directions(gest_seg_np, "ridge",
@@ -268,6 +275,8 @@ def get_vertices_and_edges_from_segmentation(gest_seg_np, *,
268
  threshold=threshold,
269
  min_line_length=min_line_length,
270
  max_line_gap=max_line_gap,
 
 
271
  **kwargs)
272
 
273
  rake_edges, rake_directions = get_lines_and_directions(gest_seg_np, "rake",
@@ -295,12 +304,14 @@ def get_vertices_and_edges_from_segmentation(gest_seg_np, *,
295
  return [], []
296
 
297
  vertex_size = np.full(len(vertices), point_radius/2)
298
- apex_radii *= point_radius_scale
299
- eave_radii *= point_radius_scale
300
- apex_radii = np.clip(apex_radii, 10, point_radius)
301
- eave_radii = np.clip(eave_radii, 10, point_radius)
302
- vertex_size[:len(apex_radii)] = apex_radii
303
- vertex_size[len(apex_radii):len(apex_radii) + len(eave_radii)] = eave_radii
 
 
304
 
305
  # for i, coords in enumerate(vertices):
306
  # coords = np.round(coords).astype(np.uint32)
@@ -553,7 +564,7 @@ def clean_points3d(entry, clustering_eps):
553
 
554
  return points3d_kdtree, biggest_cluster_keys, image_dict
555
 
556
- def get_depthmap_from_pointcloud(image, pointcloud, biggest_cluster_keys, R, t):
557
  belonging_points3d = []
558
  belonging_points2d = []
559
  point_indices = np.where(image.point3D_ids != -1)[0]
@@ -582,6 +593,57 @@ def get_depthmap_from_pointcloud(image, pointcloud, biggest_cluster_keys, R, t):
582
  # projected2d = projected2d[important[0]]
583
  projected2d = belonging_points2d[important[0]]
584
  return projected2d, depth
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
585
  def predict(entry, visualize=False,
586
  scale_estimation_coefficient=2.5,
587
  clustering_eps=100,
@@ -597,6 +659,8 @@ def predict(entry, visualize=False,
597
  vert_edge_per_image = {}
598
 
599
  points3d_kdtree, biggest_cluster_keys, image_dict = clean_points3d(entry, clustering_eps)
 
 
600
 
601
 
602
  for i, (gest, depthcm, K, R, t, imagekey) in enumerate(zip(entry['gestalt'],
@@ -615,14 +679,18 @@ def predict(entry, visualize=False,
615
  print(f'Not enough vertices or connections in image {i}')
616
  vert_edge_per_image[i] = np.empty((0, 2)), [], np.empty((0, 3))
617
  continue
 
618
  depth_np = np.array(depthcm) / scale_estimation_coefficient
 
619
  # kernel = np.array([[-1,-1,-1], [-1,9,-1], [-1,-1,-1]])
620
  # depth_np = cv2.filter2D(depth_np, -1, kernel)
621
  uv, depth_vert_from_depth_map = get_uv_depth(vertices, depth_np)
 
622
  try:
 
623
  image = image_dict[imagekey]
624
 
625
- projected2d, depth = get_depthmap_from_pointcloud(image, entry["points3d"], biggest_cluster_keys, R, t)
626
  if len(depth) < 1:
627
  print(f'No 3D points in image {i}')
628
  # vert_edge_per_image[i] = np.empty((0, 2)), [], np.empty((0, 3))
@@ -639,6 +707,9 @@ def predict(entry, visualize=False,
639
 
640
  except KeyError:
641
  #Revert to the depthmap
 
 
 
642
  depthmap_used = True
643
 
644
  # Normalize the uv to the camera intrinsics
@@ -672,7 +743,7 @@ def predict(entry, visualize=False,
672
  vertices_3d_local /= norm_factor_max
673
  else:
674
  vertices_3d_local[depth_vert_nan_idxs] /= norm_factor_max
675
- vertices_3d_local[~np.isin(np.arange(len(vertices_3d_local)), depth_vert_nan_idxs)] /= norm_factor_min
676
 
677
  world_to_cam = np.eye(4)
678
  world_to_cam[:3, :3] = R
@@ -682,11 +753,11 @@ def predict(entry, visualize=False,
682
  vertices_3d = cv2.transform(cv2.convertPointsToHomogeneous(vertices_3d_local), cam_to_world)
683
  vertices_3d = cv2.convertPointsFromHomogeneous(vertices_3d).reshape(-1, 3)
684
 
685
- if not depthmap_used:
686
- not_nan_items = np.all(~np.isnan(vertices_3d), axis=1)
687
- _, closest_fitted = points3d_kdtree.query(vertices_3d[not_nan_items])
688
-
689
- vertices_3d[not_nan_items] = points3d_kdtree.data[closest_fitted]
690
 
691
  vert_edge_per_image[i] = vertices, connections, vertices_3d
692
  all_3d_vertices, connections_3d = merge_vertices_3d(vert_edge_per_image, **kwargs)
 
146
  *_, apex_stats, apex_centroids = cv2.connectedComponentsWithStats(apex_mask, connectivity=4, stats=cv2.CV_32S)
147
  *_, other_stats, other_centroids = cv2.connectedComponentsWithStats(eave_end_point_mask, connectivity=4, stats=cv2.CV_32S)
148
 
149
+ return (apex_centroids[1:],
150
+ other_centroids[1:],
151
+ apex_mask,
152
+ eave_end_point_mask,
153
+ np.maximum(apex_stats[1:, cv2.CC_STAT_WIDTH], apex_stats[1:, cv2.CC_STAT_HEIGHT])/2,
154
+ np.maximum(other_stats[1:, cv2.CC_STAT_WIDTH], other_stats[1:, cv2.CC_STAT_HEIGHT])/2)
155
 
156
 
157
  def infer_vertices(image_gestalt, *, color_range=4.):
 
185
 
186
 
187
  def get_lines_and_directions(gest_seg_np, edge_class, *, color_range=4., rho, theta, threshold, min_line_length,
188
+ max_line_gap, extend=30, kernel_size=3, dilation_iterations=1, **kwargs):
189
  edge_color = np.array(gestalt_color_mapping[edge_class])
190
 
191
  mask = cv2.inRange(gest_seg_np,
192
  edge_color - color_range,
193
  edge_color + color_range)
194
  mask = cv2.morphologyEx(mask,
195
+ cv2.MORPH_DILATE, np.ones((kernel_size, kernel_size)), iterations=dilation_iterations)
196
 
197
  if not np.any(mask):
198
  return [], []
 
208
 
209
  line_directions = []
210
  edges = []
211
+
212
  for line_idx, line in enumerate(lines):
213
  for x1, y1, x2, y2 in line:
214
  if x1 < x2:
215
  x1, y1, x2, y2 = x2, y2, x1, y1
216
  direction = (np.array([x2 - x1, y2 - y1]))
217
  direction = direction / np.linalg.norm(direction)
 
218
 
219
+ for extend_value in range(0, int(extend), 5):
220
+ new_direction = extend_value * direction
221
 
222
+ x1, y1 = -new_direction + (x1, y1)
223
+ x2, y2 = + new_direction + (x2, y2)
224
 
225
+ line_directions.append(direction)
226
+ edges.append((x1, y1, x2, y2))
227
  return edges, line_directions
228
 
229
 
 
266
 
267
  rho = 1 # distance resolution in pixels of the Hough grid
268
  theta = np.pi / 180 # angular resolution in radians of the Hough grid
269
+ threshold = 40 # minimum number of votes (intersections in Hough grid cell)
270
  min_line_length = 60 # minimum number of pixels making up a line
271
  max_line_gap = 40 # maximum gap in pixels between connectable line segments
272
  ridge_edges, ridge_directions = get_lines_and_directions(gest_seg_np, "ridge",
 
275
  threshold=threshold,
276
  min_line_length=min_line_length,
277
  max_line_gap=max_line_gap,
278
+ kernel_size=3,
279
+ dilation_iterations=3,
280
  **kwargs)
281
 
282
  rake_edges, rake_directions = get_lines_and_directions(gest_seg_np, "rake",
 
304
  return [], []
305
 
306
  vertex_size = np.full(len(vertices), point_radius/2)
307
+ if len(apex_radii) > 0 and len(eave_radii) > 0:
308
+ apex_radii *= point_radius_scale
309
+ eave_radii *= point_radius_scale
310
+ apex_radii = np.maximum(apex_radii, 10)
311
+ eave_radii = np.maximum(eave_radii, 10)
312
+ point_radius = np.max([np.max(apex_radii), np.max(eave_radii)])
313
+ vertex_size[:len(apex_radii)] = apex_radii
314
+ vertex_size[len(apex_radii):len(apex_radii) + len(eave_radii)] = eave_radii
315
 
316
  # for i, coords in enumerate(vertices):
317
  # coords = np.round(coords).astype(np.uint32)
 
564
 
565
  return points3d_kdtree, biggest_cluster_keys, image_dict
566
 
567
+ def get_depth_from_pointcloud(image, pointcloud, biggest_cluster_keys, R, t):
568
  belonging_points3d = []
569
  belonging_points2d = []
570
  point_indices = np.where(image.point3D_ids != -1)[0]
 
593
  # projected2d = projected2d[important[0]]
594
  projected2d = belonging_points2d[important[0]]
595
  return projected2d, depth
596
+
597
+ def get_depthmap_from_pointcloud(pointcloud, biggest_cluster_keys, K, R, t, depthmap):
598
+ belonging_points3d = []
599
+ for point_id in biggest_cluster_keys:
600
+ belonging_points3d.append(pointcloud[point_id].xyz)
601
+ belonging_points3d = np.array(belonging_points3d)
602
+
603
+ projected2d, _ = cv2.projectPoints(belonging_points3d, R, t, K, 0)
604
+ projected2d = projected2d.reshape(-1, 2)
605
+ important = np.where(np.all(projected2d >= 0, axis=1))[0]
606
+ # Normalize the uv to the camera intrinsics
607
+ world_to_cam = np.eye(4)
608
+ world_to_cam[:3, :3] = R
609
+ world_to_cam[:3, 3] = t
610
+
611
+ homo_belonging_points = cv2.convertPointsToHomogeneous(belonging_points3d)
612
+ depth = cv2.convertPointsFromHomogeneous(cv2.transform(homo_belonging_points, world_to_cam))
613
+ depth = depth[:, 0, 2]
614
+ # projected2d = projected2d[:, 0, :]
615
+ depth = depth[important]
616
+ projected2d = projected2d[important]
617
+
618
+ projected2d = projected2d.astype(np.int32)
619
+ projected2d[:, 1] = np.clip(projected2d[:, 1], 0, depthmap.shape[1]-1)
620
+ projected2d[:, 0] = np.clip(projected2d[:, 0], 0, depthmap.shape[0]-1)
621
+ pointcloud_depthmap = np.full_like(depthmap, 4000)
622
+
623
+ sorted_indices = np.argsort(depth)[::-1]
624
+ projected2d, depth = projected2d[sorted_indices], depth[sorted_indices]
625
+ idx = np.searchsorted(depth, 1000)
626
+ projected2d, depth = projected2d[:idx], depth[:idx]
627
+ for point, depth_value in zip(projected2d, depth):
628
+ cv2.circle(pointcloud_depthmap, point, 20, depth_value, -1)
629
+ return pointcloud_depthmap
630
+
631
+ def get_mesh_depthmap(mesh, K, R, t, depthmap, fill_value=4000):
632
+
633
+ world_to_cam = np.eye(4)
634
+ world_to_cam[:3, :3] = R
635
+ world_to_cam[:3, 3] = t
636
+ camera_transform = np.linalg.inv(world_to_cam)
637
+ import trimesh
638
+ camera = trimesh.scene.Camera(focal=(K[0, 0], K[1, 1]), resolution=depthmap.shape[::-1])
639
+ scene = trimesh.scene.scene.Scene(camera=camera, camera_transform=camera_transform)
640
+ ray_origins, ray_directions, corresponding_pixels = scene.camera_rays()
641
+ locations, index_ray, index_tri = mesh.ray.intersects_location(ray_origins, -ray_directions, multiple_hits=False)
642
+ mesh_depths = np.linalg.norm(ray_origins[index_ray] - locations, axis=1)
643
+ mesh_depthmap = np.full(camera.resolution, fill_value)
644
+ mesh_depthmap[corresponding_pixels[index_ray, 0], corresponding_pixels[index_ray, 1]] = mesh_depths
645
+ mesh_depthmap = cv2.flip(cv2.rotate(mesh_depthmap, cv2.ROTATE_90_COUNTERCLOCKWISE), 1)
646
+ return mesh_depthmap
647
  def predict(entry, visualize=False,
648
  scale_estimation_coefficient=2.5,
649
  clustering_eps=100,
 
659
  vert_edge_per_image = {}
660
 
661
  points3d_kdtree, biggest_cluster_keys, image_dict = clean_points3d(entry, clustering_eps)
662
+ # import trimesh
663
+ # mesh = trimesh.Trimesh(vertices=entry["mesh_vertices"], faces=entry["mesh_faces"][:,1:], use_embree=True)
664
 
665
 
666
  for i, (gest, depthcm, K, R, t, imagekey) in enumerate(zip(entry['gestalt'],
 
679
  print(f'Not enough vertices or connections in image {i}')
680
  vert_edge_per_image[i] = np.empty((0, 2)), [], np.empty((0, 3))
681
  continue
682
+
683
  depth_np = np.array(depthcm) / scale_estimation_coefficient
684
+ # depth_np = get_mesh_depthmap(mesh, K, R, t, depth_np, 4000).astype(np.float32)
685
  # kernel = np.array([[-1,-1,-1], [-1,9,-1], [-1,-1,-1]])
686
  # depth_np = cv2.filter2D(depth_np, -1, kernel)
687
  uv, depth_vert_from_depth_map = get_uv_depth(vertices, depth_np)
688
+
689
  try:
690
+ # raise KeyError
691
  image = image_dict[imagekey]
692
 
693
+ projected2d, depth = get_depth_from_pointcloud(image, entry["points3d"], biggest_cluster_keys, R, t)
694
  if len(depth) < 1:
695
  print(f'No 3D points in image {i}')
696
  # vert_edge_per_image[i] = np.empty((0, 2)), [], np.empty((0, 3))
 
707
 
708
  except KeyError:
709
  #Revert to the depthmap
710
+ # if len(biggest_cluster_keys) > 0:
711
+ # depth_map = get_depthmap_from_pointcloud(entry["points3d"], biggest_cluster_keys, K, R, t, depth_np)
712
+ # uv, depth_vert_from_depth_map = get_uv_depth(vertices, depth_map)
713
  depthmap_used = True
714
 
715
  # Normalize the uv to the camera intrinsics
 
743
  vertices_3d_local /= norm_factor_max
744
  else:
745
  vertices_3d_local[depth_vert_nan_idxs] /= norm_factor_max
746
+ vertices_3d_local[~np.isin(np.arange(len(vertices_3d_local)), depth_vert_nan_idxs)] /= norm_factor_max
747
 
748
  world_to_cam = np.eye(4)
749
  world_to_cam[:3, :3] = R
 
753
  vertices_3d = cv2.transform(cv2.convertPointsToHomogeneous(vertices_3d_local), cam_to_world)
754
  vertices_3d = cv2.convertPointsFromHomogeneous(vertices_3d).reshape(-1, 3)
755
 
756
+ # if not depthmap_used:
757
+ # not_nan_items = np.all(~np.isnan(vertices_3d), axis=1)
758
+ # _, closest_fitted = points3d_kdtree.query(vertices_3d[not_nan_items])
759
+ #
760
+ # vertices_3d[not_nan_items] = points3d_kdtree.data[closest_fitted]
761
 
762
  vert_edge_per_image[i] = vertices, connections, vertices_3d
763
  all_3d_vertices, connections_3d = merge_vertices_3d(vert_edge_per_image, **kwargs)
pointclouds.ipynb ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:965401b68d1da3152141a478322bc4ebfc4d4b4b7a16b3cffefcd7c0b5e0e915
3
+ size 151533905
seek_top_level_roofs.ipynb ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:9e0d1b2dd8a7fcb8683520c0aa8890ec6b9788e669627468efe8a45a7a3ec160
3
+ size 8948456
test_solution.ipynb CHANGED
The diff for this file is too large to render. See raw diff