webapp1 commited on
Commit
83b5d87
·
verified ·
1 Parent(s): 332cede

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +20 -18
app.py CHANGED
@@ -177,8 +177,8 @@ def run_temporal_analysis(stream_id, frames_3d_copy, prob_max, prob_mean, prob_m
177
  state["rcnn"] = round(float(np.max(prob_3d)) * 100, 1)
178
 
179
  # 🚨 FIX: Strict Dual-Consensus checks to prevent IP camera frame-drop false positives!
180
- # Requires 85% overall confidence AND at least 45% spatial confirmation of an actual object collision.
181
- if confidence > 85 and yolo_max_conf > 45.0:
182
  state["final_decision"] = True
183
  state["label"] = f"Incident Logged: {severity.capitalize()}"
184
  threading.Thread(target=process_accident_async, args=(stream_id, raw_frame, location, confidence, severity)).start()
@@ -186,7 +186,7 @@ def run_temporal_analysis(stream_id, frames_3d_copy, prob_max, prob_mean, prob_m
186
  state["label"] = f"Analyzing... ({severity.capitalize()})"
187
 
188
  except Exception as e:
189
- print(f"AI Error: {e}", flush=True)
190
  finally:
191
  if state: state["is_analyzing"] = False
192
 
@@ -204,9 +204,9 @@ def init_upload():
204
  active_streams[stream_id] = {
205
  "label": "Initializing...", "final_decision": False, "confidence": 0, "severity": "--",
206
  "plates": [], "show_tracking": True, "paused": False, "seek_to": None, "skip_val": 0, "progress": 0,
207
- "cnn": 0, "rcnn": 0, "force_update": False
208
  }
209
- return jsonify({"stream_id": stream_id, "location": loc, "weather": wx, "time": file_time})
210
 
211
  @app.route('/init_stream', methods=['POST'])
212
  def init_stream():
@@ -234,9 +234,9 @@ def init_stream():
234
  active_streams[stream_id] = {
235
  "label": "Connecting...", "final_decision": False, "confidence": 0, "severity": "--",
236
  "plates": [], "show_tracking": True, "paused": False, "seek_to": None, "skip_val": 0, "progress": 0,
237
- "cnn": 0, "rcnn": 0, "force_update": False
238
  }
239
- return jsonify({"stream_id": stream_id, "location": loc, "weather": wx, "time": v_time})
240
 
241
  @app.route('/video_control/<stream_id>', methods=['POST'])
242
  def video_control(stream_id):
@@ -279,7 +279,7 @@ def video_stream_gen(stream_id, source, location):
279
 
280
  force_read = False
281
 
282
- if state.get('skip_val', 0) != 0:
283
  target = max(0, min(current_frame_idx + (state['skip_val'] * fps), total_frames - 1))
284
  cap.set(cv2.CAP_PROP_POS_FRAMES, target)
285
  current_frame_idx = int(target)
@@ -288,7 +288,7 @@ def video_stream_gen(stream_id, source, location):
288
  frames_3d.clear(); yolo_probs.clear()
289
  force_read = True
290
 
291
- if state.get('seek_to') is not None:
292
  target = int(state['seek_to'] * total_frames)
293
  cap.set(cv2.CAP_PROP_POS_FRAMES, target)
294
  current_frame_idx = target
@@ -336,7 +336,9 @@ def video_stream_gen(stream_id, source, location):
336
  h, w = frame.shape[:2]
337
  if w > 1280: frame = cv2.resize(frame, (1280, int(h * 1280 / w)))
338
 
339
- if total_frames > 0:
 
 
340
  state['progress'] = (current_frame_idx / total_frames) * 100
341
 
342
  try:
@@ -363,7 +365,7 @@ def video_stream_gen(stream_id, source, location):
363
  yolo_probs.append(probs)
364
  if len(yolo_probs) > 10: yolo_probs.pop(0)
365
 
366
- # 🚨 FIX: LIVE update of Spatial UI data so the screen doesn't feel stuck
367
  if len(yolo_probs) > 0:
368
  curr_max = np.max(yolo_probs, axis=0)
369
  acc_conf = float(np.max(curr_max[:3])) * 100 if len(curr_max) >= 3 else float(np.max(curr_max)) * 100
@@ -373,15 +375,16 @@ def video_stream_gen(stream_id, source, location):
373
 
374
  f_3d = cv2.resize(frame, (112, 112))
375
  frames_3d.append(cv2.cvtColor(f_3d, cv2.COLOR_BGR2RGB))
376
- if len(frames_3d) > 16: frames_3d.pop(0)
 
 
 
 
377
 
378
- if len(frames_3d) >= 8 and frame_count % 10 == 0 and not state.get("is_analyzing"):
379
  state["is_analyzing"] = True
380
 
381
  analysis_frames = list(frames_3d)
382
- while len(analysis_frames) < 16:
383
- analysis_frames.append(analysis_frames[-1])
384
-
385
  p_max = np.max(yolo_probs, axis=0) if len(yolo_probs) > 0 else np.zeros(4)
386
  p_mean = np.mean(yolo_probs, axis=0) if len(yolo_probs) > 0 else np.zeros(4)
387
  p_min = np.min(yolo_probs, axis=0) if len(yolo_probs) > 0 else np.zeros(4)
@@ -427,8 +430,7 @@ def predict_traffic_risk():
427
  except Exception as e: return jsonify({"error": str(e)}), 500
428
 
429
  @app.route('/favicon.ico')
430
- @app.route('/logo.png')
431
- @app.route('/logo.PNG')
432
  def serve_logo():
433
  static_dir = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'static')
434
  if os.path.exists(os.path.join(static_dir, 'logo.png')):
 
177
  state["rcnn"] = round(float(np.max(prob_3d)) * 100, 1)
178
 
179
  # 🚨 FIX: Strict Dual-Consensus checks to prevent IP camera frame-drop false positives!
180
+ # Requires 75% overall confidence AND at least 50% spatial confirmation from YOLO of an actual object collision.
181
+ if confidence > 75 and yolo_max_conf > 50.0:
182
  state["final_decision"] = True
183
  state["label"] = f"Incident Logged: {severity.capitalize()}"
184
  threading.Thread(target=process_accident_async, args=(stream_id, raw_frame, location, confidence, severity)).start()
 
186
  state["label"] = f"Analyzing... ({severity.capitalize()})"
187
 
188
  except Exception as e:
189
+ print(f"AI Error in Temporal Engine: {e}", flush=True)
190
  finally:
191
  if state: state["is_analyzing"] = False
192
 
 
204
  active_streams[stream_id] = {
205
  "label": "Initializing...", "final_decision": False, "confidence": 0, "severity": "--",
206
  "plates": [], "show_tracking": True, "paused": False, "seek_to": None, "skip_val": 0, "progress": 0,
207
+ "cnn": 0, "rcnn": 0, "force_update": False, "is_live": False
208
  }
209
+ return jsonify({"stream_id": stream_id, "location": loc, "weather": wx, "time": file_time, "is_live": False})
210
 
211
  @app.route('/init_stream', methods=['POST'])
212
  def init_stream():
 
234
  active_streams[stream_id] = {
235
  "label": "Connecting...", "final_decision": False, "confidence": 0, "severity": "--",
236
  "plates": [], "show_tracking": True, "paused": False, "seek_to": None, "skip_val": 0, "progress": 0,
237
+ "cnn": 0, "rcnn": 0, "force_update": False, "is_live": True
238
  }
239
+ return jsonify({"stream_id": stream_id, "location": loc, "weather": wx, "time": v_time, "is_live": True})
240
 
241
  @app.route('/video_control/<stream_id>', methods=['POST'])
242
  def video_control(stream_id):
 
279
 
280
  force_read = False
281
 
282
+ if state.get('skip_val', 0) != 0 and not is_live:
283
  target = max(0, min(current_frame_idx + (state['skip_val'] * fps), total_frames - 1))
284
  cap.set(cv2.CAP_PROP_POS_FRAMES, target)
285
  current_frame_idx = int(target)
 
288
  frames_3d.clear(); yolo_probs.clear()
289
  force_read = True
290
 
291
+ if state.get('seek_to') is not None and not is_live:
292
  target = int(state['seek_to'] * total_frames)
293
  cap.set(cv2.CAP_PROP_POS_FRAMES, target)
294
  current_frame_idx = target
 
336
  h, w = frame.shape[:2]
337
  if w > 1280: frame = cv2.resize(frame, (1280, int(h * 1280 / w)))
338
 
339
+ if is_live:
340
+ state['progress'] = 100 # Hide for live
341
+ elif total_frames > 0:
342
  state['progress'] = (current_frame_idx / total_frames) * 100
343
 
344
  try:
 
365
  yolo_probs.append(probs)
366
  if len(yolo_probs) > 10: yolo_probs.pop(0)
367
 
368
+ # LIVE update of Spatial UI data
369
  if len(yolo_probs) > 0:
370
  curr_max = np.max(yolo_probs, axis=0)
371
  acc_conf = float(np.max(curr_max[:3])) * 100 if len(curr_max) >= 3 else float(np.max(curr_max)) * 100
 
375
 
376
  f_3d = cv2.resize(frame, (112, 112))
377
  frames_3d.append(cv2.cvtColor(f_3d, cv2.COLOR_BGR2RGB))
378
+
379
+ # FIX: Removed artificial frame padding. It now strictly waits for 16 genuine frames.
380
+ # This prevents network stutters from being interpreted as "crashes" by the 3D-CNN.
381
+ if len(frames_3d) > 16:
382
+ frames_3d.pop(0)
383
 
384
+ if len(frames_3d) == 16 and frame_count % 10 == 0 and not state.get("is_analyzing"):
385
  state["is_analyzing"] = True
386
 
387
  analysis_frames = list(frames_3d)
 
 
 
388
  p_max = np.max(yolo_probs, axis=0) if len(yolo_probs) > 0 else np.zeros(4)
389
  p_mean = np.mean(yolo_probs, axis=0) if len(yolo_probs) > 0 else np.zeros(4)
390
  p_min = np.min(yolo_probs, axis=0) if len(yolo_probs) > 0 else np.zeros(4)
 
430
  except Exception as e: return jsonify({"error": str(e)}), 500
431
 
432
  @app.route('/favicon.ico')
433
+ @app.route('/app_logo')
 
434
  def serve_logo():
435
  static_dir = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'static')
436
  if os.path.exists(os.path.join(static_dir, 'logo.png')):