Marcel0123's picture
Update app.py
e0317f8 verified
import gradio as gr
import numpy as np
from PIL import Image, ImageDraw, ImageFont
from deepface import DeepFace
# Instellingen voor "gewoon werken"
DETECTOR = "retinaface" # nauwkeuriger dan 'opencv'
TAU = 0.65 # onder deze confidence -> "Onzeker"
ACTIONS = ["emotion"]
def analyze_batch(files, tau=TAU, show_boxes=True):
all_rows = []
visuals = []
for f in files:
img = Image.open(f).convert("RGB")
np_img = np.array(img)
try:
result = DeepFace.analyze(
img_path=np_img,
actions=ACTIONS,
detector_backend=DETECTOR,
enforce_detection=False # crash niet als er geen gezicht is
)
except Exception as e:
all_rows.append({"file": f.name, "error": str(e)})
visuals.append(img)
continue
# DeepFace kan 1 dict of list teruggeven
results = result if isinstance(result, list) else [result]
draw = ImageDraw.Draw(img.copy())
try:
font = ImageFont.truetype("DejaVuSans.ttf", 16)
except:
font = None
rows = []
for r in results:
region = r.get("region") or {}
x, y, w, h = region.get("x",0), region.get("y",0), region.get("w",0), region.get("h",0)
emotions = r.get("emotion", {})
if not emotions or w==0 or h==0:
continue
# Sorteer op score (DeepFace geeft percentages 0..100)
sorted_items = sorted(emotions.items(), key=lambda kv: kv[1], reverse=True)
top_label, top_score = sorted_items[0][0], float(sorted_items[0][1]) / 100.0
final_label = top_label if top_score >= float(tau) else "Onzeker"
rows.append({
"bbox": {"x": x, "y": y, "w": w, "h": h},
"top1": top_label,
"confidence": round(top_score,3),
"label": final_label,
"top3": [
{"label": l, "conf": round(s/100.0,3)}
for l, s in sorted_items[:3]
]
})
if show_boxes and w>0 and h>0:
draw.rectangle([x, y, x+w, y+h], outline=(0,255,0), width=3)
txt = f"{final_label} {int(top_score*100)}%"
tw, th = draw.textbbox((0,0), txt, font=font)[2:]
draw.rectangle([x, y-(th+6), x+tw+8, y], fill=(0,255,0))
draw.text((x+4, y-(th+5)), txt, fill=(0,0,0), font=font)
all_rows.append({
"file": f.name,
"faces": rows,
"note": "Geen gezichten gevonden." if not rows else f"Gezichten: {len(rows)}"
})
visuals.append(img if not rows else draw.im)
return visuals, all_rows
with gr.Blocks(title="Simpel & Betrouwbaar: Emotieherkenning") as demo:
gr.Markdown("## 😀 Emotieherkenning (serie foto’s)\n"
"- **RetinaFace** detectie + alignment\n"
"- Emoties: angry, disgust, fear, happy, sad, surprise, neutral\n"
"- Drempel voor **'Onzeker'** om fouten te voorkomen\n"
"> Let op: dit is een schatting van **gezichtsuitdrukking** (geen gemoedstoestand/intenties).")
with gr.Row():
with gr.Column(scale=1):
files = gr.File(label="Upload meerdere foto’s", file_count="multiple", type="filepath")
tau = gr.Slider(0.5, 0.9, value=TAU, step=0.01, label="Drempel τ voor 'Onzeker'")
show_boxes = gr.Checkbox(True, label="Toon kaders & labels")
btn = gr.Button("Analyseer")
with gr.Column(scale=1):
gallery = gr.Gallery(label="Resultaat (met labels)").style(grid=2, height="auto")
out_json = gr.JSON(label="Details (per foto en gezicht)")
btn.click(analyze_batch, [files, tau, show_boxes], [gallery, out_json])
if __name__ == "__main__":
demo.launch()