SecurityDemo / app.py
mkhodary101's picture
Update app.py
4e43aa1 verified
raw
history blame
11.9 kB
import gradio as gr
import torch
import cv2
import numpy as np
import time
from ultralytics import YOLO
import spaces
import os
class CrowdDetection:
def __init__(self, model_path="yolov8n.pt"):
self.model_path = model_path # Store path, load model later
@spaces.GPU
def detect_crowd(self, video_path):
try:
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
if not os.path.exists(self.model_path):
model = YOLO("yolov8n.pt")
model.save(self.model_path)
else:
model = YOLO(self.model_path)
model.to(device)
cap = cv2.VideoCapture(video_path)
if not cap.isOpened():
raise ValueError(f"❌ Failed to open video: {video_path}")
fps = int(cap.get(cv2.CAP_PROP_FPS))
width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
output_path = "output_crowd.mp4"
fourcc = cv2.VideoWriter_fourcc(*"mp4v")
out = cv2.VideoWriter(output_path, fourcc, fps, (width, height))
if not out.isOpened():
cap.release()
raise ValueError(f"❌ Failed to initialize video writer")
CROWD_THRESHOLD = 10
frame_count = 0
while cap.isOpened():
ret, frame = cap.read()
if not ret:
break
frame_count += 1
results = model(frame)
person_count = sum(1 for result in results for cls in result.boxes.cls.cpu().numpy() if int(cls) == 0)
for result in results:
boxes = result.boxes.xyxy.cpu().numpy()
classes = result.boxes.cls.cpu().numpy()
for box, cls in zip(boxes, classes):
if int(cls) == 0:
x1, y1, x2, y2 = map(int, box)
cv2.rectangle(frame, (x1, y1), (x2, y2), (0, 255, 0), 2)
cv2.putText(frame, "Person", (x1, y1 - 10), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 255, 0), 2)
alert_text = "Crowd Alert!" if person_count > CROWD_THRESHOLD else f"People: {person_count}"
cv2.putText(frame, alert_text, (50, 50), cv2.FONT_HERSHEY_SIMPLEX, 1,
(0, 0, 255) if person_count > CROWD_THRESHOLD else (0, 255, 0), 2)
out.write(frame)
cap.release()
out.release()
if frame_count == 0 or not os.path.exists(output_path):
raise ValueError("❌ Processing failed: No frames processed or output not created")
return output_path
except Exception as e:
raise ValueError(f"Error in detect_crowd: {str(e)}")
class PeopleTracking:
def __init__(self, yolo_model_path="yolov8n.pt"):
self.model_path = yolo_model_path
@spaces.GPU
def track_people(self, video_path):
try:
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
if not os.path.exists(self.model_path):
model = YOLO("yolov8n.pt")
model.save(self.model_path)
else:
model = YOLO(self.model_path)
model.to(device)
cap = cv2.VideoCapture(video_path)
if not cap.isOpened():
raise ValueError(f"❌ Failed to open video: {video_path}")
fps = int(cap.get(cv2.CAP_PROP_FPS))
width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
output_path = "output_tracking.mp4"
out = cv2.VideoWriter(output_path, cv2.VideoWriter_fourcc(*"mp4v"), fps, (width, height))
if not out.isOpened():
cap.release()
raise ValueError(f"❌ Failed to initialize video writer")
while cap.isOpened():
ret, frame = cap.read()
if not ret:
break
results = model.track(frame, persist=True)
for result in results:
boxes = result.boxes.xyxy.cpu().numpy()
classes = result.boxes.cls.cpu().numpy()
ids = result.boxes.id.cpu().numpy() if result.boxes.id is not None else np.arange(len(boxes))
for box, cls, obj_id in zip(boxes, classes, ids):
if int(cls) == 0:
x1, y1, x2, y2 = map(int, box)
cv2.rectangle(frame, (x1, y1), (x2, y2), (255, 0, 0), 2)
cv2.putText(frame, f"ID {int(obj_id)}", (x1, y1 - 10), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (255, 0, 0), 2)
out.write(frame)
cap.release()
out.release()
if not os.path.exists(output_path):
raise ValueError("❌ Processing failed")
return output_path
except Exception as e:
raise ValueError(f"Error in track_people: {str(e)}")
class FallDetection:
def __init__(self, yolo_model_path="yolov8l.pt"):
self.model_path = yolo_model_path
@spaces.GPU
def detect_fall(self, video_path):
try:
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
if not os.path.exists(self.model_path):
model = YOLO("yolov8l.pt")
model.save(self.model_path)
else:
model = YOLO(self.model_path)
model.to(device)
cap = cv2.VideoCapture(video_path)
if not cap.isOpened():
raise ValueError(f"❌ Failed to open video: {video_path}")
fps = int(cap.get(cv2.CAP_PROP_FPS))
width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
output_path = "output_fall.mp4"
out = cv2.VideoWriter(output_path, cv2.VideoWriter_fourcc(*"mp4v"), fps, (width, height))
if not out.isOpened():
cap.release()
raise ValueError(f"❌ Failed to initialize video writer")
while cap.isOpened():
ret, frame = cap.read()
if not ret:
break
results = model(frame)
for result in results:
boxes = result.boxes.xyxy.cpu().numpy()
classes = result.boxes.cls.cpu().numpy()
for box, cls in zip(boxes, classes):
if int(cls) == 0:
x1, y1, x2, y2 = map(int, box)
width = x2 - x1
height = y2 - y1
aspect_ratio = width / height if height > 0 else float('inf')
if aspect_ratio > 0.55:
color = (0, 0, 255)
label = "FALL DETECTED"
else:
color = (0, 255, 0)
label = "Standing"
cv2.rectangle(frame, (x1, y1), (x2, y2), color, 2)
cv2.putText(frame, label, (x1, y1 - 10), cv2.FONT_HERSHEY_SIMPLEX, 0.5, color, 2)
out.write(frame)
cap.release()
out.release()
if not os.path.exists(output_path):
raise ValueError("❌ Processing failed")
return output_path
except Exception as e:
raise ValueError(f"Error in detect_fall: {str(e)}")
class FightDetection:
def __init__(self, yolo_model_path="yolov8n-pose.pt"):
self.model_path = yolo_model_path
@spaces.GPU
def detect_fight(self, video_path):
try:
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
if not os.path.exists(self.model_path):
model = YOLO("yolov8n-pose.pt")
model.save(self.model_path)
else:
model = YOLO(self.model_path)
model.to(device)
cap = cv2.VideoCapture(video_path)
if not cap.isOpened():
raise ValueError(f"❌ Failed to open video: {video_path}")
fps = int(cap.get(cv2.CAP_PROP_FPS))
width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
output_path = "output_fight.mp4"
out = cv2.VideoWriter(output_path, cv2.VideoWriter_fourcc(*"mp4v"), fps, (width, height))
if not out.isOpened():
cap.release()
raise ValueError(f"❌ Failed to initialize video writer")
while cap.isOpened():
ret, frame = cap.read()
if not ret:
break
results = model.track(frame, persist=True)
fight_detected = False
person_count = 0
for result in results:
keypoints = result.keypoints.xy.cpu().numpy() if result.keypoints else []
boxes = result.boxes.xyxy.cpu().numpy() if result.boxes else []
classes = result.boxes.cls.cpu().numpy() if result.boxes else []
for box, kp, cls in zip(boxes, keypoints, classes):
if int(cls) == 0:
person_count += 1
x1, y1, x2, y2 = map(int, box)
if len(kp) > 7 and (kp[5][1] < y1 + (y2 - y1) * 0.3 or kp[7][1] < y1 + (y2 - y1) * 0.3):
fight_detected = True
cv2.rectangle(frame, (x1, y1), (x2, y2), (0, 0, 255) if fight_detected else (0, 255, 0), 2)
label = "FIGHT DETECTED" if fight_detected else "Person"
cv2.putText(frame, label, (x1, y1 - 10), cv2.FONT_HERSHEY_SIMPLEX, 0.5,
(0, 0, 255) if fight_detected else (0, 255, 0), 2)
if fight_detected and person_count > 1:
cv2.putText(frame, "FIGHT ALERT!", (50, 50), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 0, 255), 2)
out.write(frame)
cap.release()
out.release()
if not os.path.exists(output_path):
raise ValueError("❌ Processing failed")
return output_path
except Exception as e:
raise ValueError(f"Error in detect_fight: {str(e)}")
# Unified processing function with status output
def process_video(feature, video):
detectors = {
"Crowd Detection": CrowdDetection,
"People Tracking": PeopleTracking,
"Fall Detection": FallDetection,
"Fight Detection": FightDetection
}
try:
detector = detectors[feature]()
method_name = feature.lower().replace(" ", "_")
output_path = getattr(detector, method_name)(video)
return f"{feature} completed successfully", output_path
except Exception as e:
return f"Error: {str(e)}", None
# Gradio Interface with dual outputs
interface = gr.Interface(
fn=process_video,
inputs=[
gr.Dropdown(choices=["Crowd Detection", "People Tracking", "Fall Detection", "Fight Detection"], label="Select Feature"),
gr.Video(label="Upload Video")
],
outputs=[
gr.Textbox(label="Status"),
gr.Video(label="Processed Video")
],
title="YOLOv8 Multitask Video Processing",
description="Select a feature to process your video: Crowd Detection, People Tracking, Fall Detection, or Fight Detection."
)
if __name__ == "__main__":
interface.launch(debug=True)