monster07's picture
Update app.py
d08a8b7 verified
import cv2
import mediapipe as mp
import numpy as np
from datetime import datetime
import os
import gradio as gr
# Create folder for dangerous frames
os.makedirs("dangerous_frames", exist_ok=True)
dangerous_move_count = 0
mp_pose = mp.solutions.pose
mp_drawing = mp.solutions.drawing_utils
HOLD_NECK_THRESHOLD = 0.1 # Wrist-to-neck distance threshold for hold neck
# ---------------- Detection Logic ----------------
def detect_dangerous_move(landmarks):
left_wrist = landmarks[15]
right_wrist = landmarks[16]
left_elbow = landmarks[13]
right_elbow = landmarks[14]
left_shoulder = landmarks[11]
right_shoulder = landmarks[12]
left_hip = landmarks[23]
right_hip = landmarks[24]
nose = landmarks[0]
left_ankle = landmarks[27]
right_ankle = landmarks[28]
# Neck midpoint
neck_x = (left_shoulder.x + right_shoulder.x) / 2
neck_y = (left_shoulder.y + right_shoulder.y) / 2
# Distances from wrists to neck
left_wrist_to_neck = np.sqrt((left_wrist.x - neck_x) ** 2 + (left_wrist.y - neck_y) ** 2)
right_wrist_to_neck = np.sqrt((right_wrist.x - neck_x) ** 2 + (right_wrist.y - neck_y) ** 2)
# Punch
punch_left = left_wrist.y < left_shoulder.y and left_elbow.y > left_wrist.y
punch_right = right_wrist.y < right_shoulder.y and right_elbow.y > right_wrist.y
# Kick
kick_left = left_ankle.y < left_hip.y
kick_right = right_ankle.y < right_hip.y
# Block
block_left = left_elbow.y < left_shoulder.y and abs(left_wrist.x - nose.x) < 0.15
block_right = right_elbow.y < right_shoulder.y and abs(right_wrist.x - nose.x) < 0.15
blocking = block_left and block_right
# Hold neck
hold_neck = (left_wrist_to_neck < HOLD_NECK_THRESHOLD) or (right_wrist_to_neck < HOLD_NECK_THRESHOLD)
# Weapon raise
weapon_left = (left_wrist.y < left_shoulder.y - 0.1) and (left_wrist.z < left_shoulder.z)
weapon_right = (right_wrist.y < right_shoulder.y - 0.1) and (right_wrist.z < right_shoulder.z)
if hold_neck:
return "Hold Neck (Dangerous)", True
elif punch_left or punch_right:
return "Punching (Dangerous)", True
elif kick_left or kick_right:
return "Kicking (Dangerous)", True
elif blocking:
return "Blocking (Defensive)", False
elif weapon_left or weapon_right:
return "Weapon Raised (Dangerous)", True
else:
return "Normal", False
# ---------------- Main Gradio Function ----------------
def process_video(video_path):
global dangerous_move_count
dangerous_move_count = 0
cap = cv2.VideoCapture(video_path)
fourcc = cv2.VideoWriter_fourcc(*"mp4v")
out = cv2.VideoWriter("output.mp4", fourcc, 20.0, (640, 480))
with mp_pose.Pose(min_detection_confidence=0.5, min_tracking_confidence=0.5) as pose:
while cap.isOpened():
ret, frame = cap.read()
if not ret:
break
img_h, img_w, _ = frame.shape
rgb = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
pose_results = pose.process(rgb)
gesture = "No Person"
danger_move = False
landmarks = None
if pose_results.pose_landmarks:
landmarks = pose_results.pose_landmarks.landmark
gesture, danger_move = detect_dangerous_move(landmarks)
mp_drawing.draw_landmarks(frame, pose_results.pose_landmarks, mp_pose.POSE_CONNECTIONS)
if landmarks:
xs = [int(lm.x * img_w) for lm in landmarks]
ys = [int(lm.y * img_h) for lm in landmarks]
x_min, x_max = min(xs), max(xs)
y_min, y_max = min(ys), max(ys)
box_color = (0, 0, 255) if danger_move else (0, 255, 0)
cv2.rectangle(frame, (x_min, y_min), (x_max, y_max), box_color, 3)
cv2.putText(frame, gesture, (x_min, y_min - 10),
cv2.FONT_HERSHEY_SIMPLEX, 0.9, box_color, 2)
if danger_move:
dangerous_move_count += 1
timestamp = datetime.now().strftime("%Y%m%d_%H%M%S_%f")
cv2.imwrite(f"dangerous_frames/danger_{timestamp}.jpg", frame)
cv2.putText(frame, f"Dangerous Moves: {dangerous_move_count}", (10, 30),
cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 0, 255), 2)
out.write(cv2.resize(frame, (640, 480)))
cap.release()
out.release()
return "output.mp4"
# ---------------- Gradio Interface ----------------
demo = gr.Interface(
fn=process_video,
inputs=gr.Video(), # <-- FIXED (removed type="filepath")
outputs=gr.Video(),
title="⚠️ Action Recognition System (Danger Detection)",
description="Upload a video and the system will detect dangerous actions like punching, kicking, hold-neck, blocking, and weapon raise."
)
if __name__ == "__main__":
demo.launch()