jskvrna commited on
Commit
919ccdd
·
1 Parent(s): 1904e97

Filters segmented point clouds by depth and masks

Browse files

Improves the extraction of segmented point clouds by adding filtering based on depth and masks for apex and eave end points. This reduces noise and inaccuracies in the point cloud data. Additionally, switches the training loop to use the validation set.

Files changed (2) hide show
  1. predict.py +97 -2
  2. train.py +1 -1
predict.py CHANGED
@@ -595,16 +595,111 @@ def extract_segmented_pcloud(gest_seg_np, colmap_rec, img_id_substring, ade_seg,
595
  # Filter points that fall within the apex or eave_end masks
596
  filtered_points_xyz = []
597
  filtered_point_idxs = []
 
598
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
599
  for i, (u, v) in enumerate(uv):
600
  # Check if this projected point falls within the combined maskvalid_indices
601
  if combined_mask[v, u] > 0 and house_mask[v, u] > 0:
602
  original_idx = valid_indices[i] # Get original index
603
  filtered_points_xyz.append(points_xyz_world[original_idx])
604
  filtered_point_idxs.append(points_idxs[original_idx])
605
-
606
  filtered_points_xyz = np.array(filtered_points_xyz) if filtered_points_xyz else np.empty((0, 3))
607
  filtered_point_idxs = np.array(filtered_point_idxs) if filtered_point_idxs else np.empty((0,))
 
608
 
609
  '''
610
  depth_fitted, depth_sparse, _, col_img = get_fitted_dense_depth(depth, colmap_rec, img_id_substring, ade_seg, K, R, t)
@@ -663,7 +758,7 @@ def extract_segmented_pcloud(gest_seg_np, colmap_rec, img_id_substring, ade_seg,
663
  # Filtered COLMAP points in red
664
  if len(filtered_points_xyz) > 0:
665
  pcd_filtered.points = o3d.utility.Vector3dVector(filtered_points_xyz)
666
- pcd_filtered.colors = o3d.utility.Vector3dVector(np.full((len(filtered_points_xyz), 3), [1.0, 0.0, 0.0]))
667
 
668
  # Segmented depth points in blue
669
  if len(segmented_points_3d) > 0:
 
595
  # Filter points that fall within the apex or eave_end masks
596
  filtered_points_xyz = []
597
  filtered_point_idxs = []
598
+ filtered_points_color = []
599
 
600
+ # Apex
601
+ apex_color = np.array(gestalt_color_mapping['apex'])
602
+ apex_mask = cv2.inRange(gest_seg_np, apex_color-10., apex_color+10.)
603
+ if apex_mask.sum() > 0:
604
+ output = cv2.connectedComponentsWithStats(apex_mask, 8, cv2.CV_32S)
605
+ (numLabels, labels, stats, centroids) = output
606
+ stats, centroids = stats[1:], centroids[1:]
607
+ for i in range(1, numLabels):
608
+ cur_mask = labels == i
609
+ # Dilate the current mask to make it slightly larger
610
+ kernel = np.ones((5, 5), np.uint8)
611
+ cur_mask = cv2.dilate(cur_mask.astype(np.uint8), kernel, iterations=2).astype(bool)
612
+ color = np.random.rand(3)
613
+ # Create boolean mask for points in current apex mask and house mask
614
+ valid_points_mask = cur_mask[uv[:, 1], uv[:, 0]] & house_mask[uv[:, 1], uv[:, 0]]
615
+
616
+ for z in range(5):
617
+ if np.sum(valid_points_mask) < 5:
618
+ cur_mask = cv2.dilate(cur_mask.astype(np.uint8), kernel, iterations=1).astype(bool)
619
+ valid_points_mask = cur_mask[uv[:, 1], uv[:, 0]] & house_mask[uv[:, 1], uv[:, 0]]
620
+ else:
621
+ break
622
+ #
623
+ if np.any(valid_points_mask):
624
+ # Get indices of valid points
625
+ valid_point_indices = valid_indices[valid_points_mask]
626
+
627
+ # Get 3D points in camera coordinates for depth filtering
628
+ valid_world_points = points_xyz_world[valid_point_indices]
629
+ valid_cam_points = points_cam[valid_point_indices]
630
+
631
+ # Compute depths (Z coordinates in camera space)
632
+ depths = valid_cam_points[:, 2]
633
+
634
+ # Find minimum depth and filter points within min_depth + 2 meters
635
+ if len(depths) > 0:
636
+ min_depth = np.min(depths)
637
+ depth_filter = depths <= (min_depth + 2.0)
638
+
639
+ # Apply depth filter
640
+ final_valid_indices = valid_point_indices[depth_filter]
641
+
642
+ # Add corresponding points to filtered lists
643
+ filtered_points_xyz.extend(points_xyz_world[final_valid_indices])
644
+ filtered_point_idxs.extend(points_idxs[final_valid_indices])
645
+ filtered_points_color.extend([color] * np.sum(depth_filter))
646
+
647
+
648
+ # Eave end
649
+ eave_end_color = np.array(gestalt_color_mapping['eave_end_point'])
650
+ eave_end_mask = cv2.inRange(gest_seg_np, eave_end_color-10, eave_end_color+10)
651
+ if eave_end_mask.sum() > 0:
652
+ output = cv2.connectedComponentsWithStats(eave_end_mask, 8, cv2.CV_32S)
653
+ (numLabels, labels, stats, centroids) = output
654
+ stats, centroids = stats[1:], centroids[1:]
655
+ for i in range(1, numLabels):
656
+ cur_mask = labels == i
657
+ kernel = np.ones((5,5), np.uint8)
658
+ cur_mask = cv2.dilate(cur_mask.astype(np.uint8), kernel, iterations=2).astype(bool)
659
+ color = np.random.rand(3)
660
+ valid_points_mask = cur_mask[uv[:, 1], uv[:, 0]] & house_mask[uv[:, 1], uv[:, 0]]
661
+
662
+ for z in range(5):
663
+ if np.sum(valid_points_mask) < 5:
664
+ cur_mask = cv2.dilate(cur_mask.astype(np.uint8), kernel, iterations=1).astype(bool)
665
+ valid_points_mask = cur_mask[uv[:, 1], uv[:, 0]] & house_mask[uv[:, 1], uv[:, 0]]
666
+ else:
667
+ break
668
+ if np.any(valid_points_mask):
669
+ # Get indices of valid points
670
+ valid_point_indices = valid_indices[valid_points_mask]
671
+
672
+ # Get 3D points in camera coordinates for depth filtering
673
+ valid_world_points = points_xyz_world[valid_point_indices]
674
+ valid_cam_points = points_cam[valid_point_indices]
675
+
676
+ # Compute depths (Z coordinates in camera space)
677
+ depths = valid_cam_points[:, 2]
678
+
679
+ # Find minimum depth and filter points within min_depth + 2 meters
680
+ if len(depths) > 0:
681
+ min_depth = np.min(depths)
682
+ depth_filter = depths <= (min_depth + 2.0)
683
+
684
+ # Apply depth filter
685
+ final_valid_indices = valid_point_indices[depth_filter]
686
+
687
+ # Add corresponding points to filtered lists
688
+ filtered_points_xyz.extend(points_xyz_world[final_valid_indices])
689
+ filtered_point_idxs.extend(points_idxs[final_valid_indices])
690
+ filtered_points_color.extend([color] * np.sum(depth_filter))
691
+
692
+ '''
693
  for i, (u, v) in enumerate(uv):
694
  # Check if this projected point falls within the combined maskvalid_indices
695
  if combined_mask[v, u] > 0 and house_mask[v, u] > 0:
696
  original_idx = valid_indices[i] # Get original index
697
  filtered_points_xyz.append(points_xyz_world[original_idx])
698
  filtered_point_idxs.append(points_idxs[original_idx])
699
+ '''
700
  filtered_points_xyz = np.array(filtered_points_xyz) if filtered_points_xyz else np.empty((0, 3))
701
  filtered_point_idxs = np.array(filtered_point_idxs) if filtered_point_idxs else np.empty((0,))
702
+ filtered_points_color = np.array(filtered_points_color) if filtered_points_color else np.empty((0, 3))
703
 
704
  '''
705
  depth_fitted, depth_sparse, _, col_img = get_fitted_dense_depth(depth, colmap_rec, img_id_substring, ade_seg, K, R, t)
 
758
  # Filtered COLMAP points in red
759
  if len(filtered_points_xyz) > 0:
760
  pcd_filtered.points = o3d.utility.Vector3dVector(filtered_points_xyz)
761
+ pcd_filtered.colors = o3d.utility.Vector3dVector(np.array(filtered_points_color))
762
 
763
  # Segmented depth points in blue
764
  if len(segmented_points_3d) > 0:
train.py CHANGED
@@ -22,7 +22,7 @@ scores_iou = []
22
  show_visu = False
23
 
24
  idx = 0
25
- for a in ds['train']:
26
  #plot_all_modalities(a)
27
  #pred_vertices, pred_edges = predict_wireframe(a)
28
  try:
 
22
  show_visu = False
23
 
24
  idx = 0
25
+ for a in ds['validation']:
26
  #plot_all_modalities(a)
27
  #pred_vertices, pred_edges = predict_wireframe(a)
28
  try: