import gradio as gr import numpy as np from PIL import Image, ImageDraw import json from typing import Tuple, List, Dict, Any import time import threading import queue from models import load_detection_models, CV2_AVAILABLE # CV2_AVAILABLE needs to come from models.py from utils import draw_detections, process_image, generate_tone, play_sound, AlarmSystem, AUDIO_AVAILABLE # Global alarm system alarm_system = AlarmSystem() # Load models at startup face_cascade, object_net, object_classes = load_detection_models() def check_and_trigger_alarm(face_results, object_results, alarm_settings): """Check detection results and trigger alarm if conditions are met.""" if not alarm_settings.get("alarm_enabled", False): return False, "Alarm disabled" alarm_triggered = False alarm_reason = "" # Check face detection alarm if alarm_settings.get("face_alarm", False) and face_results: alarm_triggered = True alarm_reason = f"Face detected ({len(face_results)} faces)" # Check object detection alarm elif alarm_settings.get("object_alarm", False) and object_results: # Check for specific object types if specified target_objects = alarm_settings.get("target_objects", []) if target_objects: detected_objects = [obj["label"] for obj in object_results if obj["label"] in target_objects] if detected_objects: alarm_triggered = True alarm_reason = f"Target object detected: {', '.join(set(detected_objects))}" else: alarm_triggered = True alarm_reason = f"Object detected ({len(object_results)} objects)" # Trigger alarm if conditions are met if alarm_triggered: sound_type = alarm_settings.get("alarm_sound", "Beep") if sound_type == "Custom": sound_to_play = alarm_settings.get("custom_alarm_sound") else: sound_to_play = sound_type if alarm_system.trigger_alarm(sound_to_play): return True, f"đ¨ ALARM TRIGGERED: {alarm_reason}" else: return False, "Alarm cooldown active" return False, "No alarm conditions met" def recognize_face_and_objects( image: np.ndarray, enable_face_detection: bool, enable_object_detection: bool, face_confidence: float, object_confidence: float, draw_boxes: bool, show_labels: bool, box_color: str, alarm_enabled_val: bool, # New parameter for alarm_enabled face_alarm_val: bool, # New parameter for face_alarm object_alarm_val: bool, # New parameter for object_alarm alarm_sound_val: str, # New parameter for alarm_sound target_objects_val: List[str], # New parameter for target_objects custom_alarm_sound_val: str ) -> Tuple[np.ndarray, str, str, str]: """ Perform face and object detection on the input image with alarm support. """ if image is None: return None, "[]", "[]", "No image provided" # Changed this line to return empty JSON arrays for face and object results # Convert PIL to numpy if needed if isinstance(image, Image.Image): image = np.array(image) # Construct alarm_settings dictionary from the passed values alarm_settings = { "alarm_enabled": alarm_enabled_val, "face_alarm": face_alarm_val, "object_alarm": object_alarm_val, "alarm_sound": alarm_sound_val, "target_objects": target_objects_val, "custom_alarm_sound": custom_alarm_sound_val } # Process image processed_image, face_results, object_results = process_image( image, face_cascade, object_net, object_classes, enable_face_detection, enable_object_detection, face_confidence, object_confidence ) # Check alarm conditions alarm_status, alarm_message = check_and_trigger_alarm(face_results, object_results, alarm_settings) # Draw detections if requested if draw_boxes: processed_image = draw_detections( processed_image.copy(), face_results, object_results, show_labels, box_color ) # Convert results to JSON face_json = json.dumps(face_results, indent=2) if face_results else "[]" object_json = json.dumps(object_results, indent=2) if object_results else "[]" return processed_image, face_json, object_json, alarm_message def webcam_recognition( image: np.ndarray, enable_face_detection: bool, enable_object_detection: bool, face_confidence: float, object_confidence: float, draw_boxes: bool, show_labels: bool, box_color: str, alarm_enabled_val: bool, # New parameter for alarm_enabled face_alarm_val: bool, # New parameter for face_alarm object_alarm_val: bool, # New parameter for object_alarm alarm_sound_val: str, # New parameter for alarm_sound target_objects_val: List[str], # New parameter for target_objects custom_alarm_sound_val: str ) -> np.ndarray: """Real-time webcam recognition with alarm.""" if image is None: return None # Construct alarm_settings dictionary from the passed values alarm_settings = { "alarm_enabled": alarm_enabled_val, "face_alarm": face_alarm_val, "object_alarm": object_alarm_val, "alarm_sound": alarm_sound_val, "target_objects": target_objects_val } processed_image, _, _, _ = recognize_face_and_objects( image, enable_face_detection, enable_object_detection, face_confidence, object_confidence, draw_boxes, show_labels, box_color, alarm_enabled_val, # Pass these directly face_alarm_val, object_alarm_val, alarm_sound_val, target_objects_val, custom_alarm_sound_val ) return processed_image def get_detection_statistics() -> str: """Get information about available detection models.""" if CV2_AVAILABLE: stats = { "face_detection": { "model": "Haar Cascade (OpenCV)", "features": ["Face detection", "Eye detection", "Smile detection"], "speed": "Fast", "accuracy": "Medium" }, "object_detection": { "model": "OpenCV DNN with MobileNet-SSD" if object_net else "Simulation Mode", "classes": len(object_classes) if object_classes else 21, "input_size": "300x300", "speed": "Real-time capable" if object_net else "Simulation", "accuracy": "High" if object_net else "Demo Mode" } } else: stats = { "face_detection": { "model": "PIL-based Simulation", "features": ["Demo face detection"], "speed": "Fast", "accuracy": "Demo Mode", "note": "Install OpenCV for real detection" }, "object_detection": { "model": "PIL-based Simulation", "classes": 8, "input_size": "Variable", "speed": "Demo", "accuracy": "Demo Mode", "note": "Install OpenCV for real detection" } } return json.dumps(stats, indent=2) def test_alarm_sound(sound_type, custom_sound_file): """Test alarm sound.""" if not AUDIO_AVAILABLE: return "â ī¸ Audio not available. Install pyaudio for sound support." try: if sound_type == "Custom": sound_to_play = custom_sound_file if sound_to_play is None: return "Custom sound selected, but no file uploaded." else: sound_to_play = sound_type play_sound(sound_to_play) # Give a more descriptive message for custom sounds if sound_type == "Custom": return f"â Played custom sound" else: return f"â Played {sound_type} sound" except Exception as e: return f"â Error playing sound: {str(e)}" # Create custom CSS for better styling custom_css = """ .main-container { max-width: 1400px; margin: 0 auto; } .settings-panel { background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); border-radius: 10px; padding: 20px; } .result-panel { border: 2px solid #e0e0e0; border-radius: 10px; padding: 15px; } .image-container { border: 1px solid #ddd; border-radius: 8px; overflow: hidden; } .warning-box { background-color: #fff3cd; border: 1px solid #ffeaa7; border-radius: 8px; padding: 15px; margin-bottom: 20px; } .alarm-box { background-color: #f8d7da; border: 2px solid #f5c6cb; border-radius: 8px; padding: 15px; margin-bottom: 20px; animation: pulse 1s infinite; } @keyframes pulse { 0% { opacity: 1; } 50% { opacity: 0.7; } 100% { opacity: 1; } } """ with gr.Blocks(title="Face & Object Recognition Platform") as demo: gr.HTML(f"") gr.Markdown(""" # đ Face & Object Recognition Platform with Alarm System Built with [anycoder](https://huggingface.co/spaces/akhaliq/anycoder) Advanced computer vision platform for real-time face and object detection with customizable settings and alarm notifications. """) # Show warnings if dependencies are not available if not CV2_AVAILABLE: with gr.Row(): gr.Markdown("""