CoolFace
Apppublic

monster07/action_recognition_system

sourceHugging Facemitupdated 1y agoView on Hugging Face
0likes
app.py141 linesDownload Raw Back to root
1import cv22import mediapipe as mp3import numpy as np4from datetime import datetime5import os6import gradio as gr7 8# Create folder for dangerous frames9os.makedirs("dangerous_frames", exist_ok=True)10 11dangerous_move_count = 012 13mp_pose = mp.solutions.pose14mp_drawing = mp.solutions.drawing_utils15 16HOLD_NECK_THRESHOLD = 0.1  # Wrist-to-neck distance threshold for hold neck17 18 19# ---------------- Detection Logic ----------------20def detect_dangerous_move(landmarks):21    left_wrist = landmarks[15]22    right_wrist = landmarks[16]23    left_elbow = landmarks[13]24    right_elbow = landmarks[14]25    left_shoulder = landmarks[11]26    right_shoulder = landmarks[12]27    left_hip = landmarks[23]28    right_hip = landmarks[24]29    nose = landmarks[0]30    left_ankle = landmarks[27]31    right_ankle = landmarks[28]32 33    # Neck midpoint34    neck_x = (left_shoulder.x + right_shoulder.x) / 235    neck_y = (left_shoulder.y + right_shoulder.y) / 236 37    # Distances from wrists to neck38    left_wrist_to_neck = np.sqrt((left_wrist.x - neck_x) ** 2 + (left_wrist.y - neck_y) ** 2)39    right_wrist_to_neck = np.sqrt((right_wrist.x - neck_x) ** 2 + (right_wrist.y - neck_y) ** 2)40 41    # Punch42    punch_left = left_wrist.y < left_shoulder.y and left_elbow.y > left_wrist.y43    punch_right = right_wrist.y < right_shoulder.y and right_elbow.y > right_wrist.y44 45    # Kick46    kick_left = left_ankle.y < left_hip.y47    kick_right = right_ankle.y < right_hip.y48 49    # Block50    block_left = left_elbow.y < left_shoulder.y and abs(left_wrist.x - nose.x) < 0.1551    block_right = right_elbow.y < right_shoulder.y and abs(right_wrist.x - nose.x) < 0.1552    blocking = block_left and block_right53 54    # Hold neck55    hold_neck = (left_wrist_to_neck < HOLD_NECK_THRESHOLD) or (right_wrist_to_neck < HOLD_NECK_THRESHOLD)56 57    # Weapon raise58    weapon_left = (left_wrist.y < left_shoulder.y - 0.1) and (left_wrist.z < left_shoulder.z)59    weapon_right = (right_wrist.y < right_shoulder.y - 0.1) and (right_wrist.z < right_shoulder.z)60 61    if hold_neck:62        return "Hold Neck (Dangerous)", True63    elif punch_left or punch_right:64        return "Punching (Dangerous)", True65    elif kick_left or kick_right:66        return "Kicking (Dangerous)", True67    elif blocking:68        return "Blocking (Defensive)", False69    elif weapon_left or weapon_right:70        return "Weapon Raised (Dangerous)", True71    else:72        return "Normal", False73 74 75# ---------------- Main Gradio Function ----------------76def process_video(video_path):77    global dangerous_move_count78    dangerous_move_count = 079 80    cap = cv2.VideoCapture(video_path)81    fourcc = cv2.VideoWriter_fourcc(*"mp4v")82    out = cv2.VideoWriter("output.mp4", fourcc, 20.0, (640, 480))83 84    with mp_pose.Pose(min_detection_confidence=0.5, min_tracking_confidence=0.5) as pose:85        while cap.isOpened():86            ret, frame = cap.read()87            if not ret:88                break89 90            img_h, img_w, _ = frame.shape91            rgb = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)92            pose_results = pose.process(rgb)93 94            gesture = "No Person"95            danger_move = False96            landmarks = None97 98            if pose_results.pose_landmarks:99                landmarks = pose_results.pose_landmarks.landmark100                gesture, danger_move = detect_dangerous_move(landmarks)101                mp_drawing.draw_landmarks(frame, pose_results.pose_landmarks, mp_pose.POSE_CONNECTIONS)102 103            if landmarks:104                xs = [int(lm.x * img_w) for lm in landmarks]105                ys = [int(lm.y * img_h) for lm in landmarks]106                x_min, x_max = min(xs), max(xs)107                y_min, y_max = min(ys), max(ys)108 109                box_color = (0, 0, 255) if danger_move else (0, 255, 0)110                cv2.rectangle(frame, (x_min, y_min), (x_max, y_max), box_color, 3)111                cv2.putText(frame, gesture, (x_min, y_min - 10),112                            cv2.FONT_HERSHEY_SIMPLEX, 0.9, box_color, 2)113 114                if danger_move:115                    dangerous_move_count += 1116                    timestamp = datetime.now().strftime("%Y%m%d_%H%M%S_%f")117                    cv2.imwrite(f"dangerous_frames/danger_{timestamp}.jpg", frame)118 119            cv2.putText(frame, f"Dangerous Moves: {dangerous_move_count}", (10, 30),120                        cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 0, 255), 2)121 122            out.write(cv2.resize(frame, (640, 480)))123 124        cap.release()125        out.release()126 127    return "output.mp4"128 129 130# ---------------- Gradio Interface ----------------131demo = gr.Interface(132    fn=process_video,133    inputs=gr.Video(),       # <-- FIXED (removed type="filepath")134    outputs=gr.Video(),135    title="⚠️ Action Recognition System (Danger Detection)",136    description="Upload a video and the system will detect dangerous actions like punching, kicking, hold-neck, blocking, and weapon raise."137)138 139if __name__ == "__main__":140    demo.launch()141