Spaces:
Build error
Build error
Commit
·
749f08c
1
Parent(s):
d0575bf
Translate Real-time Recognition interface to English
Browse files- streamlit_app.py +212 -212
streamlit_app.py
CHANGED
|
@@ -2303,13 +2303,13 @@ def main():
|
|
| 2303 |
result_img = img.copy()
|
| 2304 |
for i, (x1, y1, x2, y2, conf) in enumerate(original_bboxes):
|
| 2305 |
cv2.rectangle(result_img, (x1, y1), (x2, y2), (0, 255, 0), 2)
|
| 2306 |
-
cv2.putText(result_img, f"
|
| 2307 |
cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 255, 0), 2)
|
| 2308 |
|
| 2309 |
# Añadir información FPS y rostros
|
| 2310 |
cv2.putText(result_img, f"FPS: {fps:.1f}", (10, 30),
|
| 2311 |
cv2.FONT_HERSHEY_SIMPLEX, 0.7, (0, 255, 0), 2)
|
| 2312 |
-
cv2.putText(result_img, f"
|
| 2313 |
cv2.FONT_HERSHEY_SIMPLEX, 0.7, (0, 255, 0), 2)
|
| 2314 |
|
| 2315 |
return av.VideoFrame.from_ndarray(result_img, format="bgr24")
|
|
@@ -2324,7 +2324,7 @@ def main():
|
|
| 2324 |
return av.VideoFrame.from_ndarray(blank, format="bgr24")
|
| 2325 |
|
| 2326 |
# Display WebRTC streamer con opciones simplificadas para mejorar compatibilidad
|
| 2327 |
-
st.info("⚠️
|
| 2328 |
webrtc_ctx = webrtc_streamer(
|
| 2329 |
key="face-recognition",
|
| 2330 |
mode=WebRtcMode.SENDRECV,
|
|
@@ -2341,250 +2341,250 @@ def main():
|
|
| 2341 |
time_metric.metric("Status", "Running")
|
| 2342 |
|
| 2343 |
# Mostrar instrucciones de uso
|
| 2344 |
-
st.success("
|
| 2345 |
else:
|
| 2346 |
faces_metric.metric("Faces detected", 0)
|
| 2347 |
fps_metric.metric("FPS", "0")
|
| 2348 |
time_metric.metric("Status", "Stopped")
|
| 2349 |
|
| 2350 |
# Mostrar instrucciones de activación
|
| 2351 |
-
st.warning("
|
| 2352 |
|
| 2353 |
# WebRTC troubleshooting
|
| 2354 |
-
with st.expander("
|
| 2355 |
st.markdown("""
|
| 2356 |
-
###
|
| 2357 |
|
| 2358 |
-
|
| 2359 |
|
| 2360 |
-
1. **
|
| 2361 |
-
2. **
|
| 2362 |
-
3. **
|
| 2363 |
|
| 2364 |
-
###
|
| 2365 |
|
| 2366 |
-
1.
|
| 2367 |
-
2.
|
| 2368 |
-
3.
|
| 2369 |
""")
|
| 2370 |
|
| 2371 |
-
|
| 2372 |
-
|
| 2373 |
-
|
| 2374 |
|
| 2375 |
-
|
| 2376 |
-
|
| 2377 |
-
|
| 2378 |
|
| 2379 |
-
|
| 2380 |
-
|
| 2381 |
-
|
| 2382 |
-
|
| 2383 |
-
|
| 2384 |
-
|
| 2385 |
-
|
| 2386 |
|
| 2387 |
-
|
| 2388 |
-
|
| 2389 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2390 |
|
| 2391 |
-
#
|
| 2392 |
-
|
| 2393 |
-
fps_metric.metric("FPS", "N/A")
|
| 2394 |
-
time_metric.metric("Status", "Running")
|
| 2395 |
|
| 2396 |
-
#
|
| 2397 |
-
|
| 2398 |
-
|
| 2399 |
-
|
| 2400 |
-
|
| 2401 |
-
|
| 2402 |
-
|
| 2403 |
-
|
| 2404 |
-
|
| 2405 |
-
|
| 2406 |
-
# Leer imagen
|
| 2407 |
-
image_bytes = captured_image.getvalue()
|
| 2408 |
-
image = cv2.imdecode(np.frombuffer(image_bytes, np.uint8), cv2.IMREAD_COLOR)
|
| 2409 |
|
| 2410 |
-
|
| 2411 |
-
|
| 2412 |
-
|
| 2413 |
-
|
| 2414 |
-
|
| 2415 |
-
|
| 2416 |
-
|
| 2417 |
-
|
| 2418 |
-
result_img
|
| 2419 |
-
|
| 2420 |
-
|
| 2421 |
-
|
| 2422 |
-
|
| 2423 |
-
|
| 2424 |
-
|
| 2425 |
-
#
|
| 2426 |
-
st.
|
| 2427 |
-
|
| 2428 |
-
|
| 2429 |
-
|
| 2430 |
-
|
| 2431 |
-
|
|
|
|
| 2432 |
|
| 2433 |
-
|
| 2434 |
-
|
| 2435 |
-
|
| 2436 |
-
|
| 2437 |
-
|
| 2438 |
-
|
| 2439 |
-
|
| 2440 |
-
|
| 2441 |
-
|
| 2442 |
-
|
| 2443 |
-
|
| 2444 |
-
embedding = openface_model(face_img)
|
| 2445 |
-
elif model_choice == "ArcFace":
|
| 2446 |
-
embedding = arcface_model(face_img)
|
| 2447 |
-
else: # Default to VGG-Face
|
| 2448 |
-
embedding = vggface_model(face_img)
|
| 2449 |
-
|
| 2450 |
-
# Comparar con rostros registrados
|
| 2451 |
-
best_match = None
|
| 2452 |
-
best_similarity = -1
|
| 2453 |
-
|
| 2454 |
-
for name, info in st.session_state.face_database.items():
|
| 2455 |
-
if 'embeddings' in info and info['embeddings']:
|
| 2456 |
-
for emb_info in info['embeddings']:
|
| 2457 |
-
if emb_info['model'] == model_choice:
|
| 2458 |
-
stored_emb = emb_info['embedding']
|
| 2459 |
-
similarity = cosine_similarity(embedding, stored_emb)
|
| 2460 |
-
|
| 2461 |
-
if similarity > similarity_threshold and similarity > best_similarity:
|
| 2462 |
-
best_similarity = similarity
|
| 2463 |
-
best_match = name
|
| 2464 |
-
|
| 2465 |
-
if best_match is not None:
|
| 2466 |
-
recognition_results.append({
|
| 2467 |
-
'bbox': bbox,
|
| 2468 |
-
'name': best_match,
|
| 2469 |
-
'similarity': best_similarity
|
| 2470 |
-
})
|
| 2471 |
|
| 2472 |
-
#
|
| 2473 |
-
|
| 2474 |
-
|
| 2475 |
-
|
| 2476 |
-
|
| 2477 |
-
|
| 2478 |
-
|
| 2479 |
-
|
| 2480 |
-
|
| 2481 |
-
|
| 2482 |
-
|
| 2483 |
-
|
| 2484 |
-
|
| 2485 |
-
|
| 2486 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2487 |
|
| 2488 |
-
#
|
| 2489 |
-
|
| 2490 |
-
|
| 2491 |
-
|
| 2492 |
-
|
| 2493 |
-
|
| 2494 |
-
|
| 2495 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2496 |
else:
|
| 2497 |
-
st.
|
| 2498 |
-
|
| 2499 |
-
st.success(f"Se detectaron {len(bboxes)} rostros")
|
| 2500 |
else:
|
| 2501 |
-
st.
|
|
|
|
|
|
|
| 2502 |
else:
|
| 2503 |
-
st.
|
| 2504 |
-
|
| 2505 |
-
st.error(
|
| 2506 |
-
|
|
|
|
|
|
|
| 2507 |
|
| 2508 |
-
|
| 2509 |
-
|
| 2510 |
-
|
| 2511 |
-
|
| 2512 |
-
|
| 2513 |
-
|
| 2514 |
|
| 2515 |
-
|
| 2516 |
-
|
| 2517 |
-
|
| 2518 |
-
|
| 2519 |
-
|
| 2520 |
-
|
| 2521 |
-
|
| 2522 |
-
|
| 2523 |
|
| 2524 |
-
|
| 2525 |
-
|
| 2526 |
-
|
| 2527 |
-
|
| 2528 |
-
|
| 2529 |
-
|
| 2530 |
-
|
| 2531 |
-
|
| 2532 |
-
|
| 2533 |
-
|
| 2534 |
-
|
| 2535 |
-
|
| 2536 |
-
|
| 2537 |
-
|
| 2538 |
-
|
| 2539 |
-
|
| 2540 |
-
|
| 2541 |
-
|
| 2542 |
-
|
| 2543 |
-
|
| 2544 |
-
|
| 2545 |
-
|
| 2546 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2547 |
|
| 2548 |
-
#
|
| 2549 |
-
|
| 2550 |
|
| 2551 |
-
#
|
| 2552 |
-
|
| 2553 |
-
|
| 2554 |
-
|
|
|
|
|
|
|
|
|
|
| 2555 |
|
| 2556 |
-
|
| 2557 |
-
|
| 2558 |
-
# Modo de carga de imagen
|
| 2559 |
-
if st.session_state.get('upload_mode', False):
|
| 2560 |
-
uploaded_file = st.file_uploader("Sube una imagen con rostros", type=["jpg", "jpeg", "png"], key="upload_image_input")
|
| 2561 |
|
| 2562 |
-
|
| 2563 |
-
|
| 2564 |
-
|
| 2565 |
-
image = cv2.imdecode(np.frombuffer(image_bytes, np.uint8), cv2.IMREAD_COLOR)
|
| 2566 |
-
|
| 2567 |
-
# Detectar rostros
|
| 2568 |
-
bboxes = detect_face_dnn(face_net, image, confidence_threshold)
|
| 2569 |
-
|
| 2570 |
-
# Dibujar rostros detectados
|
| 2571 |
-
result_img = image.copy()
|
| 2572 |
-
for i, bbox in enumerate(bboxes):
|
| 2573 |
-
x1, y1, x2, y2, _ = bbox
|
| 2574 |
-
cv2.rectangle(result_img, (x1, y1), (x2, y2), (0, 255, 0), 2)
|
| 2575 |
-
cv2.putText(result_img, f"Face {i+1}", (x1, y1-10),
|
| 2576 |
-
cv2.FONT_HERSHEY_SIMPLEX, 0.6, (0, 255, 0), 2)
|
| 2577 |
-
|
| 2578 |
-
# Mostrar resultado
|
| 2579 |
-
st.image(result_img, channels="BGR", caption="Rostros detectados", use_column_width=True)
|
| 2580 |
-
|
| 2581 |
-
# Actualizar métricas
|
| 2582 |
-
faces_metric.metric("Faces detected", len(bboxes))
|
| 2583 |
-
time_metric.metric("Status", "Processed")
|
| 2584 |
|
| 2585 |
-
|
| 2586 |
-
|
| 2587 |
-
|
| 2588 |
|
| 2589 |
# Si se ejecuta este archivo directamente, llamar a la función main
|
| 2590 |
if __name__ == "__main__":
|
|
|
|
| 2303 |
result_img = img.copy()
|
| 2304 |
for i, (x1, y1, x2, y2, conf) in enumerate(original_bboxes):
|
| 2305 |
cv2.rectangle(result_img, (x1, y1), (x2, y2), (0, 255, 0), 2)
|
| 2306 |
+
cv2.putText(result_img, f"Face {i+1}: {conf:.2f}", (x1, y1-10),
|
| 2307 |
cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 255, 0), 2)
|
| 2308 |
|
| 2309 |
# Añadir información FPS y rostros
|
| 2310 |
cv2.putText(result_img, f"FPS: {fps:.1f}", (10, 30),
|
| 2311 |
cv2.FONT_HERSHEY_SIMPLEX, 0.7, (0, 255, 0), 2)
|
| 2312 |
+
cv2.putText(result_img, f"Faces: {self.face_count}", (10, 60),
|
| 2313 |
cv2.FONT_HERSHEY_SIMPLEX, 0.7, (0, 255, 0), 2)
|
| 2314 |
|
| 2315 |
return av.VideoFrame.from_ndarray(result_img, format="bgr24")
|
|
|
|
| 2324 |
return av.VideoFrame.from_ndarray(blank, format="bgr24")
|
| 2325 |
|
| 2326 |
# Display WebRTC streamer con opciones simplificadas para mejorar compatibilidad
|
| 2327 |
+
st.info("⚠️ If the video doesn't load: Try using Chrome, reload the page, or use the alternative options below.")
|
| 2328 |
webrtc_ctx = webrtc_streamer(
|
| 2329 |
key="face-recognition",
|
| 2330 |
mode=WebRtcMode.SENDRECV,
|
|
|
|
| 2341 |
time_metric.metric("Status", "Running")
|
| 2342 |
|
| 2343 |
# Mostrar instrucciones de uso
|
| 2344 |
+
st.success("Webcam activated. Detected faces will be identified in real-time.")
|
| 2345 |
else:
|
| 2346 |
faces_metric.metric("Faces detected", 0)
|
| 2347 |
fps_metric.metric("FPS", "0")
|
| 2348 |
time_metric.metric("Status", "Stopped")
|
| 2349 |
|
| 2350 |
# Mostrar instrucciones de activación
|
| 2351 |
+
st.warning("Click START to activate the webcam. This feature may not be available in environments like Hugging Face Spaces due to security restrictions.")
|
| 2352 |
|
| 2353 |
# WebRTC troubleshooting
|
| 2354 |
+
with st.expander("Help: WebRTC Issues"):
|
| 2355 |
st.markdown("""
|
| 2356 |
+
### WebRTC Troubleshooting
|
| 2357 |
|
| 2358 |
+
If real-time recognition is not working, it may be due to the following reasons:
|
| 2359 |
|
| 2360 |
+
1. **Security restrictions in Hugging Face Spaces**: Some browsers restrict camera access in environments like this.
|
| 2361 |
+
2. **Connection problems**: WebRTC requires establishing a connection that may be blocked by firewalls or proxies.
|
| 2362 |
+
3. **Camera permissions**: You may need to grant explicit permissions to the browser to access your camera.
|
| 2363 |
|
| 2364 |
+
### What to do:
|
| 2365 |
|
| 2366 |
+
1. Try using another browser (Chrome usually works better)
|
| 2367 |
+
2. Make sure you have granted camera permissions when the browser requests them
|
| 2368 |
+
3. If it still doesn't work, use the alternative options shown below
|
| 2369 |
""")
|
| 2370 |
|
| 2371 |
+
# Añadir opción de cámara alternativa para entornos donde WebRTC no funciona bien
|
| 2372 |
+
st.markdown("---")
|
| 2373 |
+
st.markdown("### Alternative Camera Mode")
|
| 2374 |
|
| 2375 |
+
col1, col2 = st.columns(2)
|
| 2376 |
+
simple_camera = col1.button("Use Simple Camera", key="simple_camera_button1", use_container_width=True)
|
| 2377 |
+
stop_simple_camera = col2.button("Stop Camera", key="stop_camera_button1", use_container_width=True)
|
| 2378 |
|
| 2379 |
+
if simple_camera:
|
| 2380 |
+
st.session_state.simple_camera = True
|
| 2381 |
+
st.session_state.demo_running = False
|
| 2382 |
+
st.session_state.upload_mode = False
|
| 2383 |
+
|
| 2384 |
+
if stop_simple_camera:
|
| 2385 |
+
st.session_state.simple_camera = False
|
| 2386 |
|
| 2387 |
+
if st.session_state.get('simple_camera', False):
|
| 2388 |
+
# Contenedor para la cámara
|
| 2389 |
+
camera_container = st.container()
|
| 2390 |
+
|
| 2391 |
+
# Configurar métricas
|
| 2392 |
+
faces_metric.metric("Faces detected", 0)
|
| 2393 |
+
fps_metric.metric("FPS", "N/A")
|
| 2394 |
+
time_metric.metric("Status", "Running")
|
| 2395 |
+
|
| 2396 |
+
# Cámara simple que toma una imagen a la vez
|
| 2397 |
+
with camera_container:
|
| 2398 |
+
st.info("Simple camera activated. Each image is processed individually. Take a photo with your camera to detect faces.")
|
| 2399 |
|
| 2400 |
+
# Usar imagen de la cámara
|
| 2401 |
+
captured_image = st.camera_input("Take photo for recognition", key="camera_simple_input")
|
|
|
|
|
|
|
| 2402 |
|
| 2403 |
+
# Procesar la imagen si está disponible
|
| 2404 |
+
if captured_image is not None:
|
| 2405 |
+
try:
|
| 2406 |
+
# Leer imagen
|
| 2407 |
+
image_bytes = captured_image.getvalue()
|
| 2408 |
+
image = cv2.imdecode(np.frombuffer(image_bytes, np.uint8), cv2.IMREAD_COLOR)
|
| 2409 |
+
|
| 2410 |
+
if image is not None and image.size > 0:
|
| 2411 |
+
# Detectar rostros
|
| 2412 |
+
bboxes = detect_face_dnn(face_net, image, confidence_threshold)
|
|
|
|
|
|
|
|
|
|
| 2413 |
|
| 2414 |
+
# Actualizar métricas
|
| 2415 |
+
faces_metric.metric("Faces detected", len(bboxes))
|
| 2416 |
+
|
| 2417 |
+
# Dibujar resultados
|
| 2418 |
+
result_img = image.copy()
|
| 2419 |
+
for i, bbox in enumerate(bboxes):
|
| 2420 |
+
x1, y1, x2, y2, conf = bbox
|
| 2421 |
+
cv2.rectangle(result_img, (x1, y1), (x2, y2), (0, 255, 0), 2)
|
| 2422 |
+
cv2.putText(result_img, f"Face {i+1}: {conf:.2f}", (x1, y1-10),
|
| 2423 |
+
cv2.FONT_HERSHEY_SIMPLEX, 0.6, (0, 255, 0), 2)
|
| 2424 |
+
|
| 2425 |
+
# Mostrar resultado
|
| 2426 |
+
st.image(result_img, channels="BGR", caption="Detected faces", use_column_width=True)
|
| 2427 |
+
|
| 2428 |
+
if len(bboxes) > 0:
|
| 2429 |
+
# Si hay rostros registrados, intentar reconocerlos
|
| 2430 |
+
if st.session_state.face_database and len(st.session_state.face_database) > 0:
|
| 2431 |
+
st.subheader("Face Recognition:")
|
| 2432 |
+
|
| 2433 |
+
recognition_results = []
|
| 2434 |
+
for i, bbox in enumerate(bboxes):
|
| 2435 |
+
x1, y1, x2, y2, _ = bbox
|
| 2436 |
+
face_img = image[y1:y2, x1:x2]
|
| 2437 |
|
| 2438 |
+
# Extraer el embedding del rostro
|
| 2439 |
+
if model_choice == "VGG-Face":
|
| 2440 |
+
embedding = vggface_model(face_img)
|
| 2441 |
+
elif model_choice == "Facenet":
|
| 2442 |
+
embedding = facenet_model(face_img)
|
| 2443 |
+
elif model_choice == "OpenFace":
|
| 2444 |
+
embedding = openface_model(face_img)
|
| 2445 |
+
elif model_choice == "ArcFace":
|
| 2446 |
+
embedding = arcface_model(face_img)
|
| 2447 |
+
else: # Default to VGG-Face
|
| 2448 |
+
embedding = vggface_model(face_img)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2449 |
|
| 2450 |
+
# Comparar con rostros registrados
|
| 2451 |
+
best_match = None
|
| 2452 |
+
best_similarity = -1
|
| 2453 |
+
|
| 2454 |
+
for name, info in st.session_state.face_database.items():
|
| 2455 |
+
if 'embeddings' in info and info['embeddings']:
|
| 2456 |
+
for emb_info in info['embeddings']:
|
| 2457 |
+
if emb_info['model'] == model_choice:
|
| 2458 |
+
stored_emb = emb_info['embedding']
|
| 2459 |
+
similarity = cosine_similarity(embedding, stored_emb)
|
| 2460 |
+
|
| 2461 |
+
if similarity > similarity_threshold and similarity > best_similarity:
|
| 2462 |
+
best_similarity = similarity
|
| 2463 |
+
best_match = name
|
| 2464 |
+
|
| 2465 |
+
if best_match is not None:
|
| 2466 |
+
recognition_results.append({
|
| 2467 |
+
'bbox': bbox,
|
| 2468 |
+
'name': best_match,
|
| 2469 |
+
'similarity': best_similarity
|
| 2470 |
+
})
|
| 2471 |
+
|
| 2472 |
+
# Mostrar resultados de reconocimiento
|
| 2473 |
+
if recognition_results:
|
| 2474 |
+
result_with_names = result_img.copy()
|
| 2475 |
+
for result in recognition_results:
|
| 2476 |
+
x1, y1, x2, y2, _ = result['bbox']
|
| 2477 |
+
name = result['name']
|
| 2478 |
+
similarity = result['similarity']
|
| 2479 |
|
| 2480 |
+
# Dibujar nombre y similitud
|
| 2481 |
+
cv2.rectangle(result_with_names, (x1, y1), (x2, y2), (0, 255, 0), 2)
|
| 2482 |
+
label = f"{name}: {similarity:.2f}"
|
| 2483 |
+
cv2.putText(result_with_names, label, (x1, y1-10),
|
| 2484 |
+
cv2.FONT_HERSHEY_SIMPLEX, 0.6, (0, 255, 0), 2)
|
| 2485 |
+
|
| 2486 |
+
st.image(result_with_names, channels="BGR", caption="Recognized faces", use_column_width=True)
|
| 2487 |
+
|
| 2488 |
+
# Mostrar tabla de resultados
|
| 2489 |
+
results_df = pd.DataFrame([
|
| 2490 |
+
{"Name": r['name'], "Confidence": f"{r['similarity']:.2f}"}
|
| 2491 |
+
for r in recognition_results
|
| 2492 |
+
])
|
| 2493 |
+
st.table(results_df)
|
| 2494 |
else:
|
| 2495 |
+
st.warning("Could not recognize any of the detected faces.")
|
|
|
|
|
|
|
| 2496 |
else:
|
| 2497 |
+
st.info("No registered faces to compare. Please register faces in the 'Face Registration' section.")
|
| 2498 |
+
|
| 2499 |
+
st.success(f"{len(bboxes)} faces detected")
|
| 2500 |
else:
|
| 2501 |
+
st.warning("No faces detected. Try with better lighting or a different position.")
|
| 2502 |
+
else:
|
| 2503 |
+
st.error("Could not process the image. Try taking another photo.")
|
| 2504 |
+
except Exception as e:
|
| 2505 |
+
st.error(f"Error processing image: {str(e)}")
|
| 2506 |
+
st.info("Try taking another photo or use another option.")
|
| 2507 |
|
| 2508 |
+
# Opción alternativa en caso de problemas con WebRTC (mantenemos esta opción también)
|
| 2509 |
+
st.markdown("---")
|
| 2510 |
+
st.markdown("### Other Options")
|
| 2511 |
+
col1, col2 = st.columns(2)
|
| 2512 |
+
demo_mode = col1.button("Use Demo Mode", key="demo_button1")
|
| 2513 |
+
upload_mode = col2.button("Upload Image for Recognition", key="upload_button1")
|
| 2514 |
|
| 2515 |
+
if demo_mode:
|
| 2516 |
+
st.session_state.demo_running = True
|
| 2517 |
+
st.session_state.upload_mode = False
|
| 2518 |
+
st.session_state.simple_camera = False
|
| 2519 |
+
elif upload_mode:
|
| 2520 |
+
st.session_state.upload_mode = True
|
| 2521 |
+
st.session_state.demo_running = False
|
| 2522 |
+
st.session_state.simple_camera = False
|
| 2523 |
|
| 2524 |
+
# Modo de demostración con imágenes simuladas
|
| 2525 |
+
if st.session_state.get('demo_running', False):
|
| 2526 |
+
# Cargar algunas imágenes de ejemplo (usar tus propias imágenes si es posible)
|
| 2527 |
+
demo_img = None
|
| 2528 |
+
|
| 2529 |
+
# Intentar usar una imagen de la base de datos
|
| 2530 |
+
if st.session_state.face_database:
|
| 2531 |
+
for name, info in st.session_state.face_database.items():
|
| 2532 |
+
if 'image' in info:
|
| 2533 |
+
try:
|
| 2534 |
+
demo_img = info['image']
|
| 2535 |
+
break
|
| 2536 |
+
except:
|
| 2537 |
+
pass
|
| 2538 |
+
|
| 2539 |
+
# Si no hay imagen disponible, crear una imagen en blanco
|
| 2540 |
+
if demo_img is None:
|
| 2541 |
+
demo_img = np.ones((480, 640, 3), dtype=np.uint8) * 255
|
| 2542 |
+
# Dibujar un círculo como "cara" simulada
|
| 2543 |
+
cv2.circle(demo_img, (320, 240), 100, (0, 0, 255), -1)
|
| 2544 |
+
cv2.circle(demo_img, (280, 200), 15, (255, 255, 255), -1)
|
| 2545 |
+
cv2.circle(demo_img, (360, 200), 15, (255, 255, 255), -1)
|
| 2546 |
+
cv2.ellipse(demo_img, (320, 260), (50, 30), 0, 0, 180, (255, 255, 255), -1)
|
| 2547 |
+
|
| 2548 |
+
# Mostrar la imagen
|
| 2549 |
+
st.image(demo_img, channels="BGR", caption="Demo Mode", use_column_width=True)
|
| 2550 |
+
|
| 2551 |
+
# Simular métricas
|
| 2552 |
+
faces_metric.metric("Faces detected", 1)
|
| 2553 |
+
fps_metric.metric("FPS", "15.5")
|
| 2554 |
+
time_metric.metric("Status", "Demo")
|
| 2555 |
+
|
| 2556 |
+
st.success("Demo mode activated. In a local environment, real-time facial recognition would work correctly.")
|
| 2557 |
+
|
| 2558 |
+
# Modo de carga de imagen
|
| 2559 |
+
if st.session_state.get('upload_mode', False):
|
| 2560 |
+
uploaded_file = st.file_uploader("Upload an image with faces", type=["jpg", "jpeg", "png"], key="upload_image_input")
|
| 2561 |
+
|
| 2562 |
+
if uploaded_file is not None:
|
| 2563 |
+
# Leer imagen
|
| 2564 |
+
image_bytes = uploaded_file.read()
|
| 2565 |
+
image = cv2.imdecode(np.frombuffer(image_bytes, np.uint8), cv2.IMREAD_COLOR)
|
| 2566 |
|
| 2567 |
+
# Detectar rostros
|
| 2568 |
+
bboxes = detect_face_dnn(face_net, image, confidence_threshold)
|
| 2569 |
|
| 2570 |
+
# Dibujar rostros detectados
|
| 2571 |
+
result_img = image.copy()
|
| 2572 |
+
for i, bbox in enumerate(bboxes):
|
| 2573 |
+
x1, y1, x2, y2, _ = bbox
|
| 2574 |
+
cv2.rectangle(result_img, (x1, y1), (x2, y2), (0, 255, 0), 2)
|
| 2575 |
+
cv2.putText(result_img, f"Face {i+1}", (x1, y1-10),
|
| 2576 |
+
cv2.FONT_HERSHEY_SIMPLEX, 0.6, (0, 255, 0), 2)
|
| 2577 |
|
| 2578 |
+
# Mostrar resultado
|
| 2579 |
+
st.image(result_img, channels="BGR", caption="Detected faces", use_column_width=True)
|
|
|
|
|
|
|
|
|
|
| 2580 |
|
| 2581 |
+
# Actualizar métricas
|
| 2582 |
+
faces_metric.metric("Faces detected", len(bboxes))
|
| 2583 |
+
time_metric.metric("Status", "Processed")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2584 |
|
| 2585 |
+
# Add a note about privacy
|
| 2586 |
+
st.markdown("---")
|
| 2587 |
+
st.markdown("**Privacy Note**: Video is processed in your browser and on the server. No video data is stored permanently.")
|
| 2588 |
|
| 2589 |
# Si se ejecuta este archivo directamente, llamar a la función main
|
| 2590 |
if __name__ == "__main__":
|