| """ |
| π Human Activity Recognition β Gradio Demo |
| Fine-tuned MobileNetV2 classifying 15 human activities from images. |
| Model: Rishi2455/Human-Activity-Recognition |
| """ |
|
|
| import os |
| import gradio as gr |
| import tensorflow as tf |
| import numpy as np |
| from PIL import Image |
| from huggingface_hub import hf_hub_download |
|
|
| |
| MODEL_REPO = "Rishi2455/Human-Activity-Recognition" |
| MODEL_FILE = "mobilenetv2_finetuned.h5" |
| IMG_SIZE = (224, 224) |
|
|
| CLASS_NAMES = [ |
| "Calling", "Clapping", "Cycling", "Dancing", "Drinking", |
| "Eating", "Fighting", "Hugging", "Laughing", "Listening to Music", |
| "Running", "Sitting", "Sleeping", "Texting", "Using Laptop", |
| ] |
|
|
| ACTIVITY_EMOJI = { |
| "Calling": "π", "Clapping": "π", "Cycling": "π΄", "Dancing": "π", |
| "Drinking": "π₯€", "Eating": "π½οΈ", "Fighting": "π₯", "Hugging": "π€", |
| "Laughing": "π", "Listening to Music": "π§", "Running": "π", |
| "Sitting": "πͺ", "Sleeping": "π΄", "Texting": "π±", "Using Laptop": "π»", |
| } |
|
|
| |
| print("β¬οΈ Downloading model...") |
| model_path = hf_hub_download(repo_id=MODEL_REPO, filename=MODEL_FILE) |
| print("π§ Loading model...") |
| model = tf.keras.models.load_model(model_path, compile=False) |
| print("β
Model loaded!") |
|
|
| |
| EXAMPLE_DIR = "examples" |
| EXAMPLE_FILES = [ |
| "calling.jpg", "clapping.jpg", "cycling.jpg", "dancing.jpg", |
| "drinking.jpg", "eating.jpg", "fighting.jpg", "hugging.jpg", |
| "laughing.jpg", "listening_to_music.jpg", "running.jpg", |
| "sitting.jpg", "sleeping.jpg", "texting.jpg", "using_laptop.jpg", |
| ] |
| example_paths = [ |
| os.path.join(EXAMPLE_DIR, f) |
| for f in EXAMPLE_FILES |
| if os.path.exists(os.path.join(EXAMPLE_DIR, f)) |
| ] |
| print(f"πΈ Found {len(example_paths)} example images.") |
|
|
| |
| def predict(pil_img: Image.Image) -> dict: |
| """Classify a human activity from an image.""" |
| if pil_img is None: |
| return {} |
| img = pil_img.convert("RGB").resize(IMG_SIZE) |
| arr = np.expand_dims(np.array(img, dtype=np.float32), axis=0) |
| arr = tf.keras.applications.mobilenet_v2.preprocess_input(arr) |
| preds = model.predict(arr, verbose=0)[0] |
| emoji_labels = { |
| f"{ACTIVITY_EMOJI.get(c, '')} {c}": float(preds[i]) |
| for i, c in enumerate(CLASS_NAMES) |
| } |
| return emoji_labels |
|
|
| def clear_all(): |
| """Reset both image and predictions.""" |
| return None, None |
|
|
| |
| DESCRIPTION = """ |
| Upload a photo of a person performing an activity, and the model will predict which of **15 activities** they are doing. |
| |
| **Supported activities:** Calling Β· Clapping Β· Cycling Β· Dancing Β· Drinking Β· Eating Β· Fighting Β· Hugging Β· Laughing Β· Listening to Music Β· Running Β· Sitting Β· Sleeping Β· Texting Β· Using Laptop |
| |
| **Model:** [MobileNetV2](https://huggingface.co/Rishi2455/Human-Activity-Recognition) fine-tuned on the [Human Action Recognition dataset](https://huggingface.co/datasets/Bingsu/Human_Action_Recognition) |
| """ |
|
|
| css = """ |
| .main-header { text-align: center; margin-bottom: 0.5rem; } |
| .main-header h1 { font-size: 2.2rem; margin-bottom: 0; } |
| .footer { text-align: center; margin-top: 1rem; color: #888; font-size: 0.85rem; } |
| """ |
|
|
| with gr.Blocks( |
| theme=gr.themes.Soft( |
| primary_hue="blue", |
| secondary_hue="sky", |
| font=gr.themes.GoogleFont("Inter"), |
| ), |
| css=css, |
| title="π Human Activity Recognition", |
| analytics_enabled=False, |
| ) as demo: |
|
|
| |
| gr.HTML(""" |
| <div class="main-header"> |
| <h1>π Human Activity Recognition</h1> |
| <p style="color: #555; font-size: 1.1rem;">Powered by MobileNetV2 Β· 15 Activity Classes</p> |
| </div> |
| """) |
|
|
| gr.Markdown(DESCRIPTION) |
|
|
| with gr.Row(equal_height=True): |
| with gr.Column(scale=1): |
| image_input = gr.Image( |
| type="pil", |
| label="πΈ Upload Image", |
| sources=["upload", "webcam", "clipboard"], |
| height=380, |
| ) |
| with gr.Row(): |
| clear_btn = gr.Button( |
| "ποΈ Clear", |
| variant="secondary", |
| size="lg", |
| ) |
| submit_btn = gr.Button( |
| "π Classify Activity", |
| variant="primary", |
| size="lg", |
| ) |
|
|
| with gr.Column(scale=1): |
| label_output = gr.Label( |
| num_top_classes=5, |
| label="π Prediction Results", |
| ) |
|
|
| |
| if example_paths: |
| gr.Examples( |
| examples=example_paths, |
| inputs=image_input, |
| outputs=label_output, |
| fn=predict, |
| cache_examples=True, |
| label="πΌοΈ Try these examples β one for each activity", |
| ) |
|
|
| |
| clear_btn.click( |
| fn=clear_all, |
| inputs=[], |
| outputs=[image_input, label_output], |
| ) |
| submit_btn.click( |
| fn=predict, |
| inputs=image_input, |
| outputs=label_output, |
| api_name="predict", |
| ) |
| image_input.change( |
| fn=predict, |
| inputs=image_input, |
| outputs=label_output, |
| api_name=False, |
| ) |
|
|
| |
| gr.HTML(""" |
| <div class="footer"> |
| Made with β€οΈ using <a href="https://www.gradio.app/" target="_blank">Gradio</a> & |
| <a href="https://huggingface.co/" target="_blank">Hugging Face</a> Β· |
| <a href="https://huggingface.co/Rishi2455/Human-Activity-Recognition" target="_blank">Model Card</a> |
| </div> |
| """) |
|
|
| |
| demo.launch(show_api=True) |
|
|