nishanth-saka commited on
Commit
89ab605
·
verified ·
1 Parent(s): 521f194

Dominant-Flow Visualizer Adjustments

Browse files
Files changed (1) hide show
  1. app.py +39 -19
app.py CHANGED
@@ -13,7 +13,7 @@ def extract_motion_vectors(data):
13
  continue
14
  diffs = np.diff(pts, axis=0)
15
  for d in diffs:
16
- if np.linalg.norm(d) > 1: # ignore jitter
17
  vectors.append(d)
18
  return np.array(vectors)
19
 
@@ -34,7 +34,8 @@ def learn_flows(vectors, n_clusters=2):
34
  # 🎨 3. Visualization utility
35
  # ------------------------------------------------------------
36
  def draw_flow_overlay(vectors, labels, centers, bg_img=None):
37
- if bg_img:
 
38
  bg = cv2.imread(bg_img)
39
  if bg is None:
40
  bg = np.ones((600,900,3),dtype=np.uint8)*40
@@ -42,41 +43,60 @@ def draw_flow_overlay(vectors, labels, centers, bg_img=None):
42
  bg = np.ones((600,900,3),dtype=np.uint8)*40
43
 
44
  overlay = bg.copy()
45
- colors = [(255,0,0),(0,255,255)]
46
 
47
- for (vx,vy), lab in zip(vectors, labels):
48
- start = (np.random.randint(0, overlay.shape[1]), np.random.randint(0, overlay.shape[0]))
49
- end = (int(start[0]+vx*2), int(start[1]+vy*2))
 
 
 
 
 
 
 
 
50
  cv2.arrowedLine(overlay, start, end, colors[lab%2], 1, tipLength=0.3)
51
 
52
- # cluster centroids
 
 
53
  for i, c in enumerate(centers):
54
- h,w = overlay.shape[:2]
55
- center_pt = (w//2, h//2)
56
- tip = (int(center_pt[0]+c[0]*8), int(center_pt[1]+c[1]*8))
57
- cv2.arrowedLine(overlay, center_pt, tip, (0,255,0), 3, tipLength=0.4)
58
- cv2.putText(overlay, f"Flow {i+1}", (tip[0]+10, tip[1]), cv2.FONT_HERSHEY_SIMPLEX,0.6,(0,255,0),2)
 
 
 
59
 
60
- tmp_path = tempfile.NamedTemporaryFile(suffix=".jpg", delete=False).name
61
- cv2.imwrite(tmp_path, overlay)
62
- return tmp_path
63
 
64
 
65
  # ------------------------------------------------------------
66
  # 🚀 4. Combined pipeline
67
  # ------------------------------------------------------------
68
  def process_json(json_file, background=None):
69
- data = json.load(open(json_file))
 
 
 
 
70
  vectors = extract_motion_vectors(data)
71
  if len(vectors)==0:
72
  return None, {"error":"No motion vectors found."}
 
73
  labels, centers = learn_flows(vectors)
74
  if labels is None:
75
  return None, {"error":"Insufficient data for clustering."}
 
76
  img_path = draw_flow_overlay(vectors, labels, centers, background)
77
  stats = {
78
- "num_vectors": len(vectors),
79
- "dominant_flows": len(centers),
80
  "flow_centers": centers.tolist()
81
  }
82
  return img_path, stats
@@ -88,7 +108,7 @@ def process_json(json_file, background=None):
88
  description_text = """
89
  ### 🧭 Dominant Flow Learning (Stage 2)
90
  Upload the **trajectories JSON** from Stage 1 (vehicle tracking).
91
- Optionally upload a background road frame image to visualize motion arrows.
92
  """
93
 
94
  example_json = "trajectories_sample.json" if os.path.exists("trajectories_sample.json") else None
 
13
  continue
14
  diffs = np.diff(pts, axis=0)
15
  for d in diffs:
16
+ if np.linalg.norm(d) > 1: # ignore jitter / static points
17
  vectors.append(d)
18
  return np.array(vectors)
19
 
 
34
  # 🎨 3. Visualization utility
35
  # ------------------------------------------------------------
36
  def draw_flow_overlay(vectors, labels, centers, bg_img=None):
37
+ # background setup
38
+ if bg_img and os.path.exists(bg_img):
39
  bg = cv2.imread(bg_img)
40
  if bg is None:
41
  bg = np.ones((600,900,3),dtype=np.uint8)*40
 
43
  bg = np.ones((600,900,3),dtype=np.uint8)*40
44
 
45
  overlay = bg.copy()
46
+ colors = [(0,0,255),(255,255,0)] # red & yellow for lanes
47
 
48
+ # Normalize arrow lengths
49
+ norms = np.linalg.norm(vectors, axis=1, keepdims=True)
50
+ vectors = np.divide(vectors, norms + 1e-6) * 10
51
+
52
+ # Draw sampled small flow lines
53
+ for i, ((vx,vy), lab) in enumerate(zip(vectors, labels)):
54
+ if i % 15 != 0: # draw 1 of every 15 for clarity
55
+ continue
56
+ start = (np.random.randint(0, overlay.shape[1]),
57
+ np.random.randint(0, overlay.shape[0]))
58
+ end = (int(start[0]+vx), int(start[1]+vy))
59
  cv2.arrowedLine(overlay, start, end, colors[lab%2], 1, tipLength=0.3)
60
 
61
+ # Draw two main flow centroids (green)
62
+ h,w = overlay.shape[:2]
63
+ center_pt = (w//2, h//2)
64
  for i, c in enumerate(centers):
65
+ end = (int(center_pt[0]+c[0]*40), int(center_pt[1]+c[1]*40))
66
+ cv2.arrowedLine(overlay, center_pt, end, (0,255,0), 4, tipLength=0.4)
67
+ cv2.putText(overlay, f"Flow {i+1}", (end[0]+10, end[1]),
68
+ cv2.FONT_HERSHEY_SIMPLEX, 0.8, (0,255,0), 2)
69
+
70
+ # Blend overlay with background (transparency)
71
+ alpha = 0.6
72
+ combined = cv2.addWeighted(bg, alpha, overlay, 1-alpha, 0)
73
 
74
+ out_path = tempfile.NamedTemporaryFile(suffix=".jpg", delete=False).name
75
+ cv2.imwrite(out_path, combined)
76
+ return out_path
77
 
78
 
79
  # ------------------------------------------------------------
80
  # 🚀 4. Combined pipeline
81
  # ------------------------------------------------------------
82
  def process_json(json_file, background=None):
83
+ try:
84
+ data = json.load(open(json_file))
85
+ except Exception as e:
86
+ return None, {"error": f"Invalid JSON file: {e}"}
87
+
88
  vectors = extract_motion_vectors(data)
89
  if len(vectors)==0:
90
  return None, {"error":"No motion vectors found."}
91
+
92
  labels, centers = learn_flows(vectors)
93
  if labels is None:
94
  return None, {"error":"Insufficient data for clustering."}
95
+
96
  img_path = draw_flow_overlay(vectors, labels, centers, background)
97
  stats = {
98
+ "num_vectors": int(len(vectors)),
99
+ "dominant_flows": int(len(centers)),
100
  "flow_centers": centers.tolist()
101
  }
102
  return img_path, stats
 
108
  description_text = """
109
  ### 🧭 Dominant Flow Learning (Stage 2)
110
  Upload the **trajectories JSON** from Stage 1 (vehicle tracking).
111
+ Optionally upload a background road frame image for overlay visualization.
112
  """
113
 
114
  example_json = "trajectories_sample.json" if os.path.exists("trajectories_sample.json") else None