improved edge connection. (but not favorable when depth is still bad)
Browse files- handcrafted_solution.py +65 -14
handcrafted_solution.py
CHANGED
|
@@ -164,7 +164,7 @@ def get_smooth_uv_depth(vertices, depth, gest_seg_np, sfm_depth_np):
|
|
| 164 |
vertex_depth = np.array(vertex_depth)
|
| 165 |
return uv, vertex_depth
|
| 166 |
|
| 167 |
-
|
| 168 |
from numba import njit, prange
|
| 169 |
@njit(parallel=True)
|
| 170 |
def fill_range(u, v, z, dilate_r, c, sfm_depth_np, sfm_color_np, H, W):
|
|
@@ -178,7 +178,7 @@ def fill_range(u, v, z, dilate_r, c, sfm_depth_np, sfm_color_np, H, W):
|
|
| 178 |
if DUMP_IMG:
|
| 179 |
sfm_color_np[j, i] = c
|
| 180 |
return sfm_depth_np, sfm_color_np
|
| 181 |
-
'''
|
| 182 |
|
| 183 |
def get_SfM_depth(points3D, depth_np, gest_seg_np, K, R, t, dilate_r = 5):
|
| 184 |
'''Project 3D sfm pointcloud to the image plane '''
|
|
@@ -207,7 +207,7 @@ def get_SfM_depth(points3D, depth_np, gest_seg_np, K, R, t, dilate_r = 5):
|
|
| 207 |
#checked = 0
|
| 208 |
#print('dim of us uv zs rgb:', len(us), len(vs), len(zs), len(rgb))
|
| 209 |
for u,v,z,c in zip(us,vs,zs, rgb):
|
| 210 |
-
|
| 211 |
sfm_depth_np, sfm_color_np = fill_range(u, v, z, dilate_r, c, sfm_depth_np, sfm_color_np, H, W)
|
| 212 |
'''
|
| 213 |
i_range = range(max(0, u - dilate_r), min(W, u + dilate_r))
|
|
@@ -221,7 +221,7 @@ def get_SfM_depth(points3D, depth_np, gest_seg_np, K, R, t, dilate_r = 5):
|
|
| 221 |
sfm_depth_np[j, i] = z
|
| 222 |
if DUMP_IMG:
|
| 223 |
sfm_color_np[j, i] = c
|
| 224 |
-
|
| 225 |
|
| 226 |
#print(f'checked {checked} pts')
|
| 227 |
|
|
@@ -239,7 +239,6 @@ def get_vertices_and_edges_from_two_segmentations(ade_seg_np, gest_seg_np, edge_
|
|
| 239 |
'''Get the vertices and edges from the gestalt segmentation mask of the house'''
|
| 240 |
vertices = []
|
| 241 |
connections = []
|
| 242 |
-
|
| 243 |
color_th = 10.0 # Cost ->2.6
|
| 244 |
|
| 245 |
#-------------------------
|
|
@@ -332,10 +331,12 @@ def get_vertices_and_edges_from_two_segmentations(ade_seg_np, gest_seg_np, edge_
|
|
| 332 |
apex_pts.append(v['xy'])
|
| 333 |
apex_pts_idxs.append(j)
|
| 334 |
apex_pts = np.array(apex_pts)
|
| 335 |
-
|
| 336 |
-
# Ridge connects two apex points
|
| 337 |
-
|
| 338 |
-
|
|
|
|
|
|
|
| 339 |
edge_color = np.array(gestalt_color_mapping[edge_class])
|
| 340 |
mask = cv2.morphologyEx(cv2.inRange(gest_seg_np,
|
| 341 |
edge_color-color_th,
|
|
@@ -368,10 +369,57 @@ def get_vertices_and_edges_from_two_segmentations(ade_seg_np, gest_seg_np, edge_
|
|
| 368 |
connected_verts = np.where(connectivity_mask[:,edge_idx])[0]
|
| 369 |
for a_i, a in enumerate(connected_verts):
|
| 370 |
for b in connected_verts[a_i+1:]:
|
| 371 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 372 |
if DUMP_IMG:
|
| 373 |
filename_edges_map = f'edges_map_{rid}.jpg'
|
| 374 |
-
|
|
|
|
| 375 |
|
| 376 |
|
| 377 |
return vertices, connections
|
|
@@ -647,15 +695,18 @@ def predict(entry, visualize=False, prune_dist_thr=600, depth_scale=2.5, ) -> Tu
|
|
| 647 |
'''
|
| 648 |
|
| 649 |
vert_edge_per_image[i] = vertices, connections, vertices_3d
|
| 650 |
-
#all_3d_vertices, connections_3d = merge_vertices_3d(vert_edge_per_image, 3.0) # TODO: 3cm looks too small
|
| 651 |
all_3d_vertices, connections_3d = merge_vertices_3d(vert_edge_per_image, 150)
|
| 652 |
#print(f'after merge, {len(all_3d_vertices)} 3d vertices and {len(connections_3d)} 3d connections')
|
| 653 |
#all_3d_vertices_clean, connections_3d_clean = prune_not_connected(all_3d_vertices, connections_3d)
|
| 654 |
all_3d_vertices, connections_3d = prune_tall(all_3d_vertices, connections_3d, 1000)
|
|
|
|
| 655 |
if len(all_3d_vertices)>35:
|
| 656 |
all_3d_vertices, connections_3d = prune_not_connected(all_3d_vertices, connections_3d)
|
| 657 |
-
|
| 658 |
-
|
|
|
|
|
|
|
| 659 |
#all_3d_vertices_clean, connections_3d_clean = all_3d_vertices, connections_3d # don't prune -> cost:2.0
|
| 660 |
#print(f'after pruning, {len(all_3d_vertices_clean)} 3d clean vertices and {len(connections_3d_clean)} 3d clean connections')
|
| 661 |
if (len(all_3d_vertices_clean) < 2) or len(connections_3d_clean) < 1:
|
|
|
|
| 164 |
vertex_depth = np.array(vertex_depth)
|
| 165 |
return uv, vertex_depth
|
| 166 |
|
| 167 |
+
|
| 168 |
from numba import njit, prange
|
| 169 |
@njit(parallel=True)
|
| 170 |
def fill_range(u, v, z, dilate_r, c, sfm_depth_np, sfm_color_np, H, W):
|
|
|
|
| 178 |
if DUMP_IMG:
|
| 179 |
sfm_color_np[j, i] = c
|
| 180 |
return sfm_depth_np, sfm_color_np
|
| 181 |
+
''''''
|
| 182 |
|
| 183 |
def get_SfM_depth(points3D, depth_np, gest_seg_np, K, R, t, dilate_r = 5):
|
| 184 |
'''Project 3D sfm pointcloud to the image plane '''
|
|
|
|
| 207 |
#checked = 0
|
| 208 |
#print('dim of us uv zs rgb:', len(us), len(vs), len(zs), len(rgb))
|
| 209 |
for u,v,z,c in zip(us,vs,zs, rgb):
|
| 210 |
+
|
| 211 |
sfm_depth_np, sfm_color_np = fill_range(u, v, z, dilate_r, c, sfm_depth_np, sfm_color_np, H, W)
|
| 212 |
'''
|
| 213 |
i_range = range(max(0, u - dilate_r), min(W, u + dilate_r))
|
|
|
|
| 221 |
sfm_depth_np[j, i] = z
|
| 222 |
if DUMP_IMG:
|
| 223 |
sfm_color_np[j, i] = c
|
| 224 |
+
'''
|
| 225 |
|
| 226 |
#print(f'checked {checked} pts')
|
| 227 |
|
|
|
|
| 239 |
'''Get the vertices and edges from the gestalt segmentation mask of the house'''
|
| 240 |
vertices = []
|
| 241 |
connections = []
|
|
|
|
| 242 |
color_th = 10.0 # Cost ->2.6
|
| 243 |
|
| 244 |
#-------------------------
|
|
|
|
| 331 |
apex_pts.append(v['xy'])
|
| 332 |
apex_pts_idxs.append(j)
|
| 333 |
apex_pts = np.array(apex_pts)
|
| 334 |
+
'''
|
| 335 |
+
# Ridge connects two apex points
|
| 336 |
+
def Ridge_connects_two_apex_points(gest_seg_np, color_th, apex_pts, edge_th):
|
| 337 |
+
conn = []
|
| 338 |
+
line_img = np.copy(gest_seg_np) * 0
|
| 339 |
+
for edge_class in ['eave', 'ridge', 'rake', 'valley']:
|
| 340 |
edge_color = np.array(gestalt_color_mapping[edge_class])
|
| 341 |
mask = cv2.morphologyEx(cv2.inRange(gest_seg_np,
|
| 342 |
edge_color-color_th,
|
|
|
|
| 369 |
connected_verts = np.where(connectivity_mask[:,edge_idx])[0]
|
| 370 |
for a_i, a in enumerate(connected_verts):
|
| 371 |
for b in connected_verts[a_i+1:]:
|
| 372 |
+
conn.append((a, b))
|
| 373 |
+
return conn, line_img
|
| 374 |
+
|
| 375 |
+
connections, line_img = Ridge_connects_two_apex_points(gest_seg_np, color_th, apex_pts, edge_th)
|
| 376 |
+
'''
|
| 377 |
+
def classifyPairs(apex_pts, apex_pts_idxs, gest_seg_np, apex_mask, eave_end_mask):
|
| 378 |
+
conn = []
|
| 379 |
+
# Plot all possible connection pixels in one mask
|
| 380 |
+
mask = cv2.bitwise_or(apex_mask, eave_end_mask)
|
| 381 |
+
for edge_class in ['eave', 'ridge', 'rake', 'valley', 'step_flashing']:
|
| 382 |
+
edge_color = np.array(gestalt_color_mapping[edge_class])
|
| 383 |
+
mask_e = cv2.morphologyEx(cv2.inRange(gest_seg_np,
|
| 384 |
+
edge_color-color_th,
|
| 385 |
+
edge_color+color_th),
|
| 386 |
+
cv2.MORPH_DILATE, np.ones((11, 11)))
|
| 387 |
+
mask = cv2.bitwise_or(mask, mask_e)
|
| 388 |
+
# try connecting each apir and see if the cost on the mask is too high
|
| 389 |
+
def count_on_line_segment(mask, x1, y1, x2, y2, num_points=100):
|
| 390 |
+
#points = []
|
| 391 |
+
score = 0
|
| 392 |
+
for t in range(num_points + 1):
|
| 393 |
+
t /= num_points
|
| 394 |
+
x = x1 + t * (x2 - x1)
|
| 395 |
+
y = y1 + t * (y2 - y1)
|
| 396 |
+
x, y = x.astype(np.int32), y.astype(np.int32)
|
| 397 |
+
if mask[y,x] >0:
|
| 398 |
+
score += 1
|
| 399 |
+
|
| 400 |
+
return score/num_points
|
| 401 |
+
#points.append((x, y))
|
| 402 |
+
#return points
|
| 403 |
+
|
| 404 |
+
conn_thr = 0.8 # 80% of pixels are connectivity pixels
|
| 405 |
+
for p1i in apex_pts_idxs:
|
| 406 |
+
for p2i in apex_pts_idxs:
|
| 407 |
+
if p1i == p2i:
|
| 408 |
+
continue
|
| 409 |
+
score = count_on_line_segment(mask, apex_pts[p1i][0], apex_pts[p1i][1], apex_pts[p2i][0], apex_pts[p2i][1], num_points=100)
|
| 410 |
+
#print(f'{p1i}, {p2i}, score = {score}')
|
| 411 |
+
if score>conn_thr and ((p2i,p1i) not in conn):
|
| 412 |
+
conn.append((p1i, p2i))
|
| 413 |
+
|
| 414 |
+
return conn, mask
|
| 415 |
+
connections, line_img = classifyPairs(apex_pts, apex_pts_idxs, gest_seg_np, apex_mask, eave_end_mask)
|
| 416 |
+
|
| 417 |
+
#print(f'{len(vertices)} vertices: {vertices}')
|
| 418 |
+
#print(len(connections), ' connections: ', connections)
|
| 419 |
if DUMP_IMG:
|
| 420 |
filename_edges_map = f'edges_map_{rid}.jpg'
|
| 421 |
+
if 'line_img' in locals():
|
| 422 |
+
cv2.imwrite(filename_edges_map, line_img)
|
| 423 |
|
| 424 |
|
| 425 |
return vertices, connections
|
|
|
|
| 695 |
'''
|
| 696 |
|
| 697 |
vert_edge_per_image[i] = vertices, connections, vertices_3d
|
| 698 |
+
#all_3d_vertices, connections_3d = merge_vertices_3d(vert_edge_per_image, 3.0) # TODO: 3cm looks too small
|
| 699 |
all_3d_vertices, connections_3d = merge_vertices_3d(vert_edge_per_image, 150)
|
| 700 |
#print(f'after merge, {len(all_3d_vertices)} 3d vertices and {len(connections_3d)} 3d connections')
|
| 701 |
#all_3d_vertices_clean, connections_3d_clean = prune_not_connected(all_3d_vertices, connections_3d)
|
| 702 |
all_3d_vertices, connections_3d = prune_tall(all_3d_vertices, connections_3d, 1000)
|
| 703 |
+
|
| 704 |
if len(all_3d_vertices)>35:
|
| 705 |
all_3d_vertices, connections_3d = prune_not_connected(all_3d_vertices, connections_3d)
|
| 706 |
+
if len(all_3d_vertices)>10:
|
| 707 |
+
all_3d_vertices_clean, connections_3d_clean = prune_far(all_3d_vertices, connections_3d, prune_dist_thr=prune_dist_thr)
|
| 708 |
+
else:
|
| 709 |
+
all_3d_vertices_clean, connections_3d_clean = all_3d_vertices, connections_3d
|
| 710 |
#all_3d_vertices_clean, connections_3d_clean = all_3d_vertices, connections_3d # don't prune -> cost:2.0
|
| 711 |
#print(f'after pruning, {len(all_3d_vertices_clean)} 3d clean vertices and {len(connections_3d_clean)} 3d clean connections')
|
| 712 |
if (len(all_3d_vertices_clean) < 2) or len(connections_3d_clean) < 1:
|