assentian1970 commited on
Commit
390fae8
·
verified ·
1 Parent(s): 2855c1d

Update yolo_detection.py

Browse files
Files changed (1) hide show
  1. yolo_detection.py +111 -0
yolo_detection.py CHANGED
@@ -209,6 +209,117 @@ def annotate_video_with_bboxes(video_path):
209
  writer.release()
210
  return annotated_video_path
211
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
212
  # File type validation
213
  IMAGE_EXTENSIONS = {'.jpg', '.jpeg', '.png', '.bmp', '.tiff', '.webp'}
214
  VIDEO_EXTENSIONS = {'.mp4', '.mkv', '.mov', '.avi', '.flv', '.wmv', '.webm', '.m4v'}
 
209
  writer.release()
210
  return annotated_video_path
211
 
212
+
213
+ def process_video_unified(media_path):
214
+ """
215
+ Single pass YOLO processing for video.
216
+ Detects people/machinery, calculates max counts, and generates an annotated video.
217
+ Returns: max_people_count, total_machinery_count, max_machine_types, annotated_video_path
218
+ """
219
+ max_people_count = 0
220
+ max_machine_types = {
221
+ "Tower Crane": 0, "Mobile Crane": 0, "Compactor/Roller": 0, "Bulldozer": 0,
222
+ "Excavator": 0, "Dump Truck": 0, "Concrete Mixer": 0, "Loader": 0,
223
+ "Pump Truck": 0, "Pile Driver": 0, "Grader": 0, "Other Vehicle": 0
224
+ }
225
+ annotated_video_path = None
226
+
227
+ try:
228
+ cap = cv2.VideoCapture(media_path)
229
+ if not cap.isOpened():
230
+ print(f"Error: Could not open video file {media_path}")
231
+ return 0, 0, {}, None
232
+
233
+ fps = cap.get(cv2.CAP_PROP_FPS)
234
+ w = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
235
+ h = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
236
+ sample_rate = max(1, int(fps)) # Sample 1 frame per second
237
+ frame_count = 0
238
+
239
+ # Create a temp file for output annotated video
240
+ out_file = tempfile.NamedTemporaryFile(suffix=".mp4", delete=False)
241
+ annotated_video_path = out_file.name
242
+ out_file.close()
243
+
244
+ fourcc = cv2.VideoWriter_fourcc(*'mp4v')
245
+ writer = cv2.VideoWriter(annotated_video_path, fourcc, fps, (w, h))
246
+
247
+ while True:
248
+ ret, frame = cap.read()
249
+ if not ret:
250
+ break
251
+
252
+ # Process every nth frame based on sample rate for stats, but annotate every frame
253
+ if frame_count % sample_rate == 0:
254
+ results = YOLO_MODEL(frame) # Run detection
255
+
256
+ # --- Calculate Max Counts ---
257
+ people, _, machine_types = process_yolo_results(results)
258
+ max_people_count = max(max_people_count, people)
259
+ for k, v in machine_types.items():
260
+ if k in max_machine_types: # Ensure key exists
261
+ max_machine_types[k] = max(max_machine_types.get(k, 0), v)
262
+
263
+ # --- Annotate Frame (using the same results) ---
264
+ frame_counts = {} # For summary text on this frame
265
+ annotated_frame = frame.copy() # Work on a copy for annotation
266
+
267
+ for r in results:
268
+ boxes = r.boxes
269
+ for box in boxes:
270
+ cls_id = int(box.cls[0])
271
+ conf = float(box.conf[0])
272
+ if conf < 0.5: continue
273
+
274
+ x1, y1, x2, y2 = map(int, box.xyxy[0])
275
+ class_name = YOLO_MODEL.names[cls_id]
276
+
277
+ # Draw bounding box
278
+ color = (0, 255, 0)
279
+ cv2.rectangle(annotated_frame, (x1, y1), (x2, y2), color, 2)
280
+ label_text = f"{class_name} {conf:.2f}"
281
+ cv2.putText(annotated_frame, label_text, (x1, y1 - 6),
282
+ cv2.FONT_HERSHEY_SIMPLEX, 0.5, (255, 255, 255), 1)
283
+
284
+ # Increment per-frame class count for summary
285
+ frame_counts[class_name] = frame_counts.get(class_name, 0) + 1
286
+
287
+ # Build and draw summary string for the frame
288
+ summary_str = ", ".join(f"{cls}: {cnt}" for cls, cnt in frame_counts.items())
289
+ cv2.putText(annotated_frame, summary_str, (15, 30),
290
+ cv2.FONT_HERSHEY_SIMPLEX, 1.0, (255, 255, 0), 2)
291
+
292
+ writer.write(annotated_frame) # Write annotated frame
293
+ else:
294
+ # If not sampling this frame for stats, still write original frame to keep video length correct
295
+ # Or optionally, run detection+annotation anyway if performance allows and annotation is desired for all frames
296
+ # For now, let's just write the original frame to maintain sync
297
+ writer.write(frame)
298
+
299
+
300
+ frame_count += 1
301
+
302
+ cap.release()
303
+ writer.release()
304
+
305
+ # Filter out zero counts from max_machine_types
306
+ max_machine_types = {k: v for k, v in max_machine_types.items() if v > 0}
307
+ total_machinery_count = sum(max_machine_types.values())
308
+
309
+ print(f"Unified processing complete. People: {max_people_count}, Machinery: {total_machinery_count}, Types: {max_machine_types}")
310
+ return max_people_count, total_machinery_count, max_machine_types, annotated_video_path
311
+
312
+ except Exception as e:
313
+ print(f"Error in unified YOLO video processing: {str(e)}")
314
+ # Clean up potentially created temp file on error
315
+ if annotated_video_path and os.path.exists(annotated_video_path):
316
+ try:
317
+ os.remove(annotated_video_path)
318
+ except OSError:
319
+ pass # Ignore error during cleanup
320
+ return 0, 0, {}, None
321
+
322
+
323
  # File type validation
324
  IMAGE_EXTENSIONS = {'.jpg', '.jpeg', '.png', '.bmp', '.tiff', '.webp'}
325
  VIDEO_EXTENSIONS = {'.mp4', '.mkv', '.mov', '.avi', '.flv', '.wmv', '.webm', '.m4v'}