import os
import sys
import numpy as np
from PIL import Image
import keras
import gradio as gr
import spaces
# 1. Dummy GPU function to satisfy HuggingFace ZeroGPU startup check
@spaces.GPU
def _dummy_startup():
pass
# 2. Load trained MobileNetV2 model once at startup
MODEL_PATH = os.getenv("MODEL_PATH", "models/human_face_v1.keras")
model = keras.models.load_model(MODEL_PATH)
CLASS_NAMES = ["human", "non_human"]
THRESHOLD = 0.5
# 3. CPU prediction function (runs cleanly in ~30ms without ZeroGPU hang)
def predict_face(img):
if img is None:
return """
Upload an image on the left to see the AI decision!
"""
# Preprocess image
image = img.convert("RGB").resize((224, 224))
pixels = np.asarray(image, dtype=np.float32)[None, ...]
p_non_human = float(model.predict(pixels, verbose=0)[0][0])
p_human = 1.0 - p_non_human
if p_human >= THRESHOLD:
pct = round(p_human * 100, 1)
return f"""
✓
It's a Human!
Confidence: {pct}%
Looks like a human! 😊
"""
else:
pct = round(p_non_human * 100, 1)
return f"""
✗
Not a Human!
Confidence: {pct}%
Looks like AI or synthetic! 🤖
"""
custom_css = """
@import url('https://fonts.googleapis.com/css2?family=Caveat:wght@600;700&family=Outfit:wght@600;700;800&family=Plus+Jakarta+Sans:wght@400;500;600;700&display=swap');
.gradio-container {
max-width: 1080px !important;
margin: 0 auto !important;
font-family: 'Plus Jakarta Sans', sans-serif !important;
background: #f8faff !important;
}
"""
with gr.Blocks(title="Humanly - Human or Not?") as demo:
# 1. Top Navbar
gr.HTML("""
""")
# 2. Hero Section with Mascot & Title
gr.HTML("""
🤖
Human or Not?
Upload an image and let AI decide!
""")
# 3. Main Two-Column Card Layout
with gr.Row():
with gr.Column(scale=1):
image_input = gr.Image(
type="pil",
label="Upload Face Image (JPG, PNG, JPEG)",
sources=["upload", "clipboard"],
)
classify_btn = gr.Button("🔍 Classify Face", variant="primary", size="lg")
with gr.Column(scale=1):
result_output = gr.HTML(
value="""
Upload an image on the left and click Classify!
"""
)
# 4. Triggers: Auto on upload + manual on button click
image_input.change(fn=predict_face, inputs=image_input, outputs=result_output)
classify_btn.click(fn=predict_face, inputs=image_input, outputs=result_output)
# 5. Footer
gr.HTML("""
Built by Jatin Karma ❤️
""")
if __name__ == "__main__":
demo.launch(css=custom_css, ssr_mode=False)