import gradio as gr import cv2 import numpy as np from PIL import Image # Load the face cascade classifier face_cascade = cv2.CascadeClassifier(cv2.data.haarcascades + 'haarcascade_frontalface_default.xml') def detect_faces(image): """ Detect faces in the input image using Haar Cascade Classifier Args: image: Input image (numpy array or PIL Image) Returns: tuple: (processed_image, face_count, status_message) """ if image is None: return None, "Please capture or upload an image first" # Convert PIL Image to numpy array if needed if isinstance(image, Image.Image): image = np.array(image) # Ensure image is in the correct format if len(image.shape) == 2: # Grayscale image = cv2.cvtColor(image, cv2.COLOR_GRAY2BGR) elif image.shape[2] == 4: # RGBA image = cv2.cvtColor(image, cv2.COLOR_RGBA2BGR) elif image.shape[2] == 3: # RGB image = cv2.cvtColor(image, cv2.COLOR_RGB2BGR) # Convert to grayscale for detection gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) # Detect faces faces = face_cascade.detectMultiScale( gray, scaleFactor=1.1, minNeighbors=5, minSize=(30, 30) ) # Draw rectangles around detected faces result_image = image.copy() for (x, y, w, h) in faces: cv2.rectangle(result_image, (x, y), (x+w, y+h), (0, 255, 0), 3) # Convert back to RGB for display result_image = cv2.cvtColor(result_image, cv2.COLOR_BGR2RGB) # Create status message if len(faces) == 0: status = "❌ No faces detected" elif len(faces) == 1: status = "✅ 1 face detected" else: status = f"✅ {len(faces)} faces detected" return result_image, status def process_image(image): """Process uploaded or captured image""" return detect_faces(image) # Custom CSS for better mobile experience custom_css = """ .gradio-container { max-width: 100% !important; } #camera-input { max-width: 100%; } .output-image { max-width: 100%; height: auto; } """ # Create Gradio interface with gr.Blocks(title="Face Detection App") as demo: gr.HTML(f"") gr.Markdown( """ # 📸 Face Detection App ### Detect faces using your phone's camera or upload an image This app uses OpenCV's Haar Cascade Classifier for real-time face detection. """ ) with gr.Tabs(): # Tab 1: Camera Input (Best for phones) with gr.Tab("📱 Phone Camera"): gr.Markdown("### Capture a photo using your phone's camera") gr.Markdown("*Tip: Grant camera permissions when prompted*") with gr.Row(): with gr.Column(): camera_input = gr.Image( sources=["webcam"], type="numpy", label="Camera Input" ) camera_btn = gr.Button("🔍 Detect Faces", variant="primary", size="lg") with gr.Column(): camera_output = gr.Image(label="Detected Faces", elem_classes=["output-image"]) camera_status = gr.Textbox(label="Status", interactive=False) camera_btn.click( fn=process_image, inputs=[camera_input], outputs=[camera_output, camera_status] ) # Tab 2: Upload Image with gr.Tab("📤 Upload Image"): gr.Markdown("### Upload an image from your device") with gr.Row(): with gr.Column(): upload_input = gr.Image( sources=["upload"], type="numpy", label="Upload Image" ) upload_btn = gr.Button("🔍 Detect Faces", variant="primary", size="lg") with gr.Column(): upload_output = gr.Image(label="Detected Faces", elem_classes=["output-image"]) upload_status = gr.Textbox(label="Status", interactive=False) upload_btn.click( fn=process_image, inputs=[upload_input], outputs=[upload_output, upload_status] ) # Information section with gr.Accordion("â„šī¸ About & Parameters", open=False): gr.Markdown( """ ### How it works This application uses **OpenCV's Haar Cascade Classifier** to detect faces in images. The classifier is a machine learning-based approach that analyzes image patterns. ### Detection Parameters ```python scaleFactor = 1.1 # Image pyramid scale minNeighbors = 5 # Quality threshold minSize = (30, 30) # Minimum face size in pixels ``` ### Tips for best results - Ensure good lighting - Face the camera directly - Keep a moderate distance from the camera - Avoid extreme angles or occlusions ### Mobile Usage - Use the "Phone Camera" tab for direct camera access - Grant camera permissions when prompted - The app works best in modern browsers (Chrome, Safari) """ ) # Launch the app if __name__ == "__main__": demo.launch( server_name="0.0.0.0", # Allow access from other devices on the network server_port=7860, # Default Gradio port share=True, # Set to True to create a public link inbrowser=True # Automatically open in browser )