PrimateFace / app.py
fparodi's picture
Update app.py
f587de8 verified
raw
history blame
6 kB
import gradio as gr
from gradio_client import Client
import os
BACKEND_URL = os.environ.get("BACKEND_URL", "").strip()
# Create persistent client
try:
client = Client(BACKEND_URL, headers={"ngrok-skip-browser-warning": "true"})
backend_available = True
except:
client = None
backend_available = False
def forward_to_backend(fn_name, *args):
"""Generic function to forward any call to backend"""
if not client:
return [gr.update() for _ in range(7)]
try:
return client.predict(*args, api_name=fn_name)
except Exception as e:
print(f"Error calling {fn_name}: {e}")
return [gr.update() for _ in range(7)]
# Wrapper functions
def handle_file_upload_preview(file_obj):
return forward_to_backend("/handle_file_upload_preview", file_obj)
def handle_webcam_capture(snapshot):
return forward_to_backend("/handle_webcam_capture", snapshot)
def process_media(file_obj, webcam_img, model_type, conf_thresh, max_dets, task_type):
return forward_to_backend("/process_media", file_obj, webcam_img, model_type, conf_thresh, max_dets, task_type)
def clear_all_media_and_outputs():
return forward_to_backend("/clear_all_media_and_outputs")
def handle_example_select(evt: gr.SelectData):
"""Handle example selection locally and update input_file"""
# Extract the image path from the dataset
if isinstance(evt.value, dict) and 'image' in evt.value:
return evt.value['image']
return None
# Build the interface
with gr.Blocks(theme=gr.themes.Soft()) as demo:
gr.Markdown("<center><h1>PrimateFace Detection, Pose Estimation, and Gaze Estimation Demo</h1></center>")
if not backend_available:
gr.Markdown("### 🔴 GPU Server Offline - Please check back later")
else:
gr.Markdown("Upload an image/video or use your webcam. For webcam, press 'Enter' to take a snapshot.")
gr.Markdown("Click 'Detect Faces' for results.")
with gr.Row():
with gr.Column(scale=1):
with gr.Tabs():
with gr.TabItem("Upload File"):
input_file = gr.File(label="Upload Image or Video Here", file_types=["image", ".mp4", ".avi", ".mov", ".mkv", ".webm", ".gif"])
display_raw_image_file = gr.Image(label="Raw Image Preview", type="pil", interactive=False, visible=False)
display_raw_video_file = gr.Video(label="Raw Video Preview", interactive=False, visible=False)
with gr.TabItem("Webcam"):
gr.Markdown("**Using the Webcam:** Click on feed or press Enter to capture")
input_webcam = gr.Image(sources=["webcam"], type="pil", label="Live Webcam")
display_raw_image_webcam = gr.Image(label="Captured Snapshot Preview", type="pil", interactive=False, visible=False)
clear_all_button = gr.Button("Clear All Inputs & Outputs")
with gr.Column(scale=1):
gr.Markdown("### Processed Output")
display_processed_image = gr.Image(label="Processed Image", type="pil", interactive=False, visible=False)
display_processed_video = gr.Video(label="Processed Video", interactive=False, visible=False)
# Example images - host them on HF Space
example_paths = [
"images/allocebus_000003.jpeg",
"images/tarsius_000120.jpeg",
"images/nasalis_proboscis-monkey.png",
"images/macaca_000032.jpeg",
"images/mandrillus_000011.jpeg",
"images/pongo_000006.jpeg"
]
example_dataset = gr.Dataset(
components=["image"],
samples=[[path] for path in example_paths],
label="Example Images (Click to use)",
samples_per_page=6
)
submit_button = gr.Button("Detect Faces", variant="primary", scale=2)
with gr.Column():
gr.Markdown("### Detection Controls")
model_choice_radio = gr.Radio(choices=["MMDetection"], value="MMDetection", label="Inferencer", visible=False)
task_type_dropdown = gr.Dropdown(
choices=["Face Detection", "Face Pose Estimation", "Gaze Estimation [experimental]"],
value="Face Detection",
label="Select Task"
)
conf_slider = gr.Slider(minimum=0.05, maximum=0.95, value=0.25, step=0.05, label="Confidence Threshold")
max_det_slider = gr.Slider(minimum=1, maximum=10, value=3, step=1, label="Max Detections")
# Define outputs
file_preview_outputs = [display_raw_image_file, display_raw_video_file, input_file, display_processed_image, display_processed_video]
webcam_outputs = [display_raw_image_webcam, input_webcam, display_processed_image, display_processed_video]
process_outputs = [display_raw_image_file, display_raw_video_file, display_raw_image_webcam, display_processed_image, display_processed_video]
clear_outputs = [input_file, input_webcam, display_raw_image_file, display_raw_video_file, display_raw_image_webcam, display_processed_image, display_processed_video]
# Wire events
input_file.change(handle_file_upload_preview, inputs=[input_file], outputs=file_preview_outputs)
input_webcam.change(handle_webcam_capture, inputs=[input_webcam], outputs=webcam_outputs)
# Handle example selection
example_dataset.select(handle_example_select, outputs=[input_file])
submit_button.click(
process_media,
inputs=[input_file, display_raw_image_webcam, model_choice_radio, conf_slider, max_det_slider, task_type_dropdown],
outputs=process_outputs
)
clear_all_button.click(clear_all_media_and_outputs, outputs=clear_outputs)
demo.launch()