LiamKhoaLe commited on
Commit
40967d9
·
1 Parent(s): f6d5295

Add debugs on A* path if they may get blocked in routing nodes. Add function to allow offfset of 3 segment classes

Browse files
Files changed (1) hide show
  1. app.py +33 -16
app.py CHANGED
@@ -85,6 +85,10 @@ ade_palette = np.array([
85
  [184, 255, 0], [0, 133, 255], [255, 214, 0], [25, 194, 194], [102, 255, 0],
86
  [92, 0, 255]
87
  ], dtype=np.uint8)
 
 
 
 
88
 
89
  custom_class_map = {
90
  "Garbage": [(255, 8, 41), (235, 255, 7), (255, 5, 153), (255, 0, 102)],
@@ -183,28 +187,39 @@ def highlight_water_mask_on_frame(frame, binary_mask, color=(255, 0, 0), alpha=0
183
  def astar(start, goal, occ):
184
  h = lambda a,b: abs(a[0]-b[0])+abs(a[1]-b[1])
185
  N8 = [(-1,-1),(-1,0),(-1,1),(0,-1),(0,1),(1,-1),(1,0),(1,1)]
186
- openq=[(0,start)]; g={start:0}; came={}
187
  while openq:
188
  _,cur=heapq.heappop(openq)
189
  if cur==goal:
190
  p=[cur]; # reconstruct
191
  while cur in came: cur=came[cur]; p.append(cur)
192
  return p[::-1]
193
- for dx,dy in N8:
194
- nx,ny=cur[0]+dx,cur[1]+dy
195
- # out-of-bounds / blocked
196
- if not (0<=nx<640 and 0<=ny<640) or occ[ny,nx]==0: continue
197
- # if diagonal, ensure both orthogonals are free
198
- if abs(dx)==1 and abs(dy)==1:
199
- if occ[cur[1]+dy, cur[0]]==0 or occ[cur[1], cur[0]+dx]==0:
 
 
200
  continue
201
- ng=g[cur]+1
202
- if (nx,ny) not in g or ng<g[(nx,ny)]:
203
- g[(nx,ny)]=ng
204
- f=ng+h((nx,ny),goal)
205
- heapq.heappush(openq,(f,(nx,ny)))
206
- came[(nx,ny)]=cur
207
- return []
 
 
 
 
 
 
 
 
 
208
  # KNN fit optimal path
209
  def knn_path(start, targets, occ):
210
  todo = targets[:]; path=[]
@@ -429,7 +444,9 @@ def _pipeline(uid,img_path):
429
  seg = cv2.resize(seg_tensor.numpy(), (640, 640), interpolation=cv2.INTER_NEAREST)
430
  print(f"🧪 [{uid}] segmentation input shape: {inputs['pixel_values'].shape}")
431
  water_mask, garbage_mask, movable_mask = build_masks(seg) # movable zone = water and garbage masks
432
- cv2.imwrite(f"{OUTPUT_DIR}/{uid}_movable_mask.png", movable_mask * 255)
 
 
433
  print(f"🧩 Saved debug movable_mask: {OUTPUT_DIR}/{uid}_movable_mask.png")
434
 
435
  # 2- Garbage detection (3 models) → keep centres on water
 
85
  [184, 255, 0], [0, 133, 255], [255, 214, 0], [25, 194, 194], [102, 255, 0],
86
  [92, 0, 255]
87
  ], dtype=np.uint8)
88
+ if ade_palette.shape[0] < 150: # Some update require 150 class now but we only afford 146, allow offset
89
+ missing = 150 - ade_palette.shape[0]
90
+ padding = np.zeros((missing, 3), dtype=np.uint8)
91
+ ade_palette = np.vstack([ade_palette, padding])
92
 
93
  custom_class_map = {
94
  "Garbage": [(255, 8, 41), (235, 255, 7), (255, 5, 153), (255, 0, 102)],
 
187
  def astar(start, goal, occ):
188
  h = lambda a,b: abs(a[0]-b[0])+abs(a[1]-b[1])
189
  N8 = [(-1,-1),(-1,0),(-1,1),(0,-1),(0,1),(1,-1),(1,0),(1,1)]
190
+ openq=[(0,start)]; g={start:0}; came={}; visited = set()
191
  while openq:
192
  _,cur=heapq.heappop(openq)
193
  if cur==goal:
194
  p=[cur]; # reconstruct
195
  while cur in came: cur=came[cur]; p.append(cur)
196
  return p[::-1]
197
+ if cur in visited:
198
+ continue
199
+ visited.add(cur)
200
+ for dx, dy in N8:
201
+ nx, ny = cur[0] + dx, cur[1] + dy
202
+ if not (0 <= nx < 640 and 0 <= ny < 640) or occ[ny, nx] == 0:
203
+ continue
204
+ if abs(dx) == 1 and abs(dy) == 1:
205
+ if occ[cur[1]+dy, cur[0]] == 0 or occ[cur[1], cur[0]+dx] == 0:
206
  continue
207
+ neighbor = (nx, ny)
208
+ ng = g[cur] + 1
209
+ if neighbor not in g or ng < g[neighbor]:
210
+ g[neighbor] = ng
211
+ f = ng + h(neighbor, goal)
212
+ heapq.heappush(openq, (f, neighbor))
213
+ came[neighbor] = cur
214
+ # Save visited search as debug image
215
+ visited_img = np.zeros_like(occ, dtype=np.uint8)
216
+ for x, y in visited:
217
+ visited_img[y, x] = 127
218
+ cv2.circle(visited_img, start[::-1], 3, 255, -1)
219
+ cv2.circle(visited_img, goal[::-1], 3, 255, -1)
220
+ cv2.imwrite("/home/user/app/outputs/debug_astar_failure.png", visited_img * 2)
221
+ print(f"🧨 A* failed from {start} to {goal} — frontier saved to debug_astar_failure.png")
222
+ return []
223
  # KNN fit optimal path
224
  def knn_path(start, targets, occ):
225
  todo = targets[:]; path=[]
 
444
  seg = cv2.resize(seg_tensor.numpy(), (640, 640), interpolation=cv2.INTER_NEAREST)
445
  print(f"🧪 [{uid}] segmentation input shape: {inputs['pixel_values'].shape}")
446
  water_mask, garbage_mask, movable_mask = build_masks(seg) # movable zone = water and garbage masks
447
+ for cx, cy in centres:
448
+ cv2.circle(movable_mask, (cx, cy), 3, 127, -1) # gray center dots
449
+ cv2.imwrite(f"{OUTPUT_DIR}/{uid}_movable_with_centres.png", movable_mask * 255)
450
  print(f"🧩 Saved debug movable_mask: {OUTPUT_DIR}/{uid}_movable_mask.png")
451
 
452
  # 2- Garbage detection (3 models) → keep centres on water