PrashanthB461 commited on
Commit
5b58187
·
verified ·
1 Parent(s): c66f0e4

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +52 -76
app.py CHANGED
@@ -64,7 +64,8 @@ CONFIG = {
64
  "MAX_PROCESSING_TIME": 60, # 1 minute limit
65
  "FRAME_SKIP": 2, # Process every 2nd frame for speed
66
  "BATCH_SIZE": 16, # Frames per batch
67
- "PARALLEL_WORKERS": max(1, cpu_count() - 1) # Use all CPU cores except one
 
68
  }
69
 
70
  # Setup logging
@@ -135,36 +136,6 @@ def calculate_iou(box1, box2):
135
 
136
  return intersection_area / union_area
137
 
138
- def process_frame_batch(frame_batch, frame_indices, fps):
139
- batch_results = []
140
- results = model(frame_batch, device=device, conf=0.1, verbose=False)
141
-
142
- for idx, (result, frame_idx) in enumerate(zip(results, frame_indices)):
143
- current_time = frame_idx / fps
144
- detections = []
145
-
146
- boxes = result.boxes
147
- for box in boxes:
148
- cls = int(box.cls)
149
- conf = float(box.conf)
150
- label = CONFIG["VIOLATION_LABELS"].get(cls, None)
151
-
152
- if label is None or conf < CONFIG["CONFIDENCE_THRESHOLDS"].get(label, 0.25):
153
- continue
154
-
155
- bbox = [round(x, 2) for x in box.xywh.cpu().numpy()[0]]
156
- detections.append({
157
- "frame": frame_idx,
158
- "violation": label,
159
- "confidence": round(conf, 2),
160
- "bounding_box": bbox,
161
- "timestamp": current_time
162
- })
163
-
164
- batch_results.append((frame_idx, detections))
165
-
166
- return batch_results
167
-
168
  def generate_violation_pdf(violations, score):
169
  try:
170
  pdf_filename = f"violations_{int(time.time())}.pdf"
@@ -336,10 +307,12 @@ def process_video(video_data):
336
 
337
  workers = []
338
  violations = []
339
- helmet_violations = {}
340
  snapshots = []
341
  start_time = time.time()
342
  frame_skip = CONFIG["FRAME_SKIP"]
 
 
 
343
 
344
  # Process frames in batches
345
  while True:
@@ -392,14 +365,7 @@ def process_video(video_data):
392
  continue
393
 
394
  bbox = [round(x, 2) for x in box.xywh.cpu().numpy()[0]]
395
- detection = {
396
- "frame": frame_idx,
397
- "violation": label,
398
- "confidence": round(conf, 2),
399
- "bounding_box": bbox,
400
- "timestamp": current_time
401
- }
402
-
403
  # Worker tracking
404
  worker_id = None
405
  max_iou = 0
@@ -420,49 +386,59 @@ def process_video(video_data):
420
  "last_seen": current_time
421
  })
422
 
423
- detection["worker_id"] = worker_id
 
 
 
 
 
424
 
425
- # Track helmet violations with stricter criteria
426
- if detection["violation"] == "no_helmet":
427
- # Only include high-confidence no_helmet detections
428
- if conf >= CONFIG["CONFIDENCE_THRESHOLDS"]["no_helmet"]:
429
- if worker_id not in helmet_violations:
430
- helmet_violations[worker_id] = []
431
- helmet_violations[worker_id].append(detection)
432
- else:
433
- violations.append(detection)
434
-
435
- # Remove inactive workers
436
- workers = [w for w in workers if current_time - w["last_seen"] < CONFIG["WORKER_TRACKING_DURATION"]]
437
-
438
- cap.release()
439
- os.remove(video_path)
440
- processing_time = time.time() - start_time
441
- logger.info(f"Processing complete in {processing_time:.2f}s. {len(violations)} violations found.")
442
 
443
- # Confirm helmet violations (require multiple detections)
444
- for worker_id, detections in helmet_violations.items():
445
- if len(detections) >= CONFIG["MIN_VIOLATION_FRAMES"]:
446
- # Select the detection with the highest confidence
447
- best_detection = max(detections, key=lambda x: x["confidence"])
448
- violations.append(best_detection)
449
-
450
- # Capture snapshot for confirmed no_helmet violation
451
- cap = cv2.VideoCapture(video_path)
452
- cap.set(cv2.CAP_PROP_POS_FRAMES, best_detection["frame"])
453
- ret, snapshot_frame = cap.read()
454
- if ret:
455
- snapshot_frame = draw_detections(snapshot_frame, [best_detection])
456
- snapshot_filename = f"no_helmet_{best_detection['frame']}.jpg"
457
  snapshot_path = os.path.join(CONFIG["OUTPUT_DIR"], snapshot_filename)
458
  cv2.imwrite(snapshot_path, snapshot_frame)
459
  snapshots.append({
460
- "violation": "no_helmet",
461
- "frame": best_detection["frame"],
 
462
  "snapshot_path": snapshot_path,
463
  "snapshot_base64": f"{CONFIG['PUBLIC_URL_BASE']}{snapshot_filename}"
464
  })
465
- cap.release()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
466
 
467
  # Generate results
468
  if not violations:
@@ -481,7 +457,7 @@ def process_video(video_data):
481
  violation_table += row
482
 
483
  snapshots_text = "\n".join(
484
- f"- Snapshot for {CONFIG['DISPLAY_NAMES'].get(s['violation'], 'Unknown')} at frame {s['frame']}: ![]({s['snapshot_base64']})"
485
  for s in snapshots
486
  ) if snapshots else "No snapshots captured."
487
 
 
64
  "MAX_PROCESSING_TIME": 60, # 1 minute limit
65
  "FRAME_SKIP": 2, # Process every 2nd frame for speed
66
  "BATCH_SIZE": 16, # Frames per batch
67
+ "PARALLEL_WORKERS": max(1, cpu_count() - 1), # Use all CPU cores except one
68
+ "VIOLATION_COOLDOWN": 5.0 # Seconds before same violation can be detected again for same worker
69
  }
70
 
71
  # Setup logging
 
136
 
137
  return intersection_area / union_area
138
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
139
  def generate_violation_pdf(violations, score):
140
  try:
141
  pdf_filename = f"violations_{int(time.time())}.pdf"
 
307
 
308
  workers = []
309
  violations = []
 
310
  snapshots = []
311
  start_time = time.time()
312
  frame_skip = CONFIG["FRAME_SKIP"]
313
+
314
+ # Track active violations to prevent duplicate detections
315
+ active_violations = {} # Format: {worker_id: {violation_type: last_detection_time}}
316
 
317
  # Process frames in batches
318
  while True:
 
365
  continue
366
 
367
  bbox = [round(x, 2) for x in box.xywh.cpu().numpy()[0]]
368
+
 
 
 
 
 
 
 
369
  # Worker tracking
370
  worker_id = None
371
  max_iou = 0
 
386
  "last_seen": current_time
387
  })
388
 
389
+ # Check if this worker already has this violation type in cooldown period
390
+ if worker_id in active_violations:
391
+ if label in active_violations[worker_id]:
392
+ last_detection_time = active_violations[worker_id][label]
393
+ if current_time - last_detection_time < CONFIG["VIOLATION_COOLDOWN"]:
394
+ continue # Skip this detection as it's within cooldown period
395
 
396
+ # Create detection record
397
+ detection = {
398
+ "frame": frame_idx,
399
+ "violation": label,
400
+ "confidence": round(conf, 2),
401
+ "bounding_box": bbox,
402
+ "timestamp": current_time,
403
+ "worker_id": worker_id
404
+ }
 
 
 
 
 
 
 
 
405
 
406
+ # Add to violations list
407
+ violations.append(detection)
408
+
409
+ # Update active violations
410
+ if worker_id not in active_violations:
411
+ active_violations[worker_id] = {}
412
+ active_violations[worker_id][label] = current_time
413
+
414
+ # Capture snapshot for this violation
415
+ snapshot_frame = batch_frames[i].copy()
416
+ snapshot_frame = draw_detections(snapshot_frame, [detection])
417
+ snapshot_filename = f"{label}_{worker_id}_{frame_idx}.jpg"
 
 
418
  snapshot_path = os.path.join(CONFIG["OUTPUT_DIR"], snapshot_filename)
419
  cv2.imwrite(snapshot_path, snapshot_frame)
420
  snapshots.append({
421
+ "violation": label,
422
+ "frame": frame_idx,
423
+ "worker_id": worker_id,
424
  "snapshot_path": snapshot_path,
425
  "snapshot_base64": f"{CONFIG['PUBLIC_URL_BASE']}{snapshot_filename}"
426
  })
427
+
428
+ # Remove inactive workers and their violations
429
+ workers = [w for w in workers if current_time - w["last_seen"] < CONFIG["WORKER_TRACKING_DURATION"]]
430
+
431
+ # Clean up active_violations for workers no longer tracked
432
+ active_violations = {
433
+ worker_id: violations
434
+ for worker_id, violations in active_violations.items()
435
+ if any(w["id"] == worker_id for w in workers)
436
+ }
437
+
438
+ cap.release()
439
+ os.remove(video_path)
440
+ processing_time = time.time() - start_time
441
+ logger.info(f"Processing complete in {processing_time:.2f}s. {len(violations)} violations found.")
442
 
443
  # Generate results
444
  if not violations:
 
457
  violation_table += row
458
 
459
  snapshots_text = "\n".join(
460
+ f"- Snapshot for {CONFIG['DISPLAY_NAMES'].get(s['violation'], 'Unknown')} (Worker {s['worker_id']}) at frame {s['frame']}: ![]({s['snapshot_base64']})"
461
  for s in snapshots
462
  ) if snapshots else "No snapshots captured."
463