2026-04-10 21:33:40 +00:00
|
|
|
import cv2
|
|
|
|
|
import os
|
|
|
|
|
import json
|
|
|
|
|
import numpy as np
|
|
|
|
|
|
|
|
|
|
# ⚡ Importamos tus motores exactos para no romper la simetría
|
|
|
|
|
from reconocimiento2 import detectar_rostros_yunet, gestionar_vectores
|
|
|
|
|
|
|
|
|
|
def registrar_desde_webcam():
|
|
|
|
|
print("\n" + "="*50)
|
|
|
|
|
print("📸 MÓDULO DE REGISTRO LIMPIO (WEBCAM LOCAL)")
|
|
|
|
|
print("Alinea tu rostro, mira a la cámara con buena luz.")
|
|
|
|
|
print("Presiona [R] para capturar | [Q] para salir")
|
|
|
|
|
print("="*50 + "\n")
|
|
|
|
|
|
|
|
|
|
DB_PATH = "db_institucion"
|
|
|
|
|
CACHE_PATH = "cache_nombres"
|
|
|
|
|
os.makedirs(DB_PATH, exist_ok=True)
|
|
|
|
|
os.makedirs(CACHE_PATH, exist_ok=True)
|
|
|
|
|
|
|
|
|
|
# 0 es la cámara por defecto de tu laptop
|
|
|
|
|
cap = cv2.VideoCapture(0)
|
|
|
|
|
if not cap.isOpened():
|
|
|
|
|
print("[!] Error: No se pudo abrir la webcam local.")
|
|
|
|
|
return
|
|
|
|
|
|
|
|
|
|
while True:
|
|
|
|
|
ret, frame = cap.read()
|
|
|
|
|
if not ret: continue
|
|
|
|
|
|
|
|
|
|
# Espejamos la imagen para que actúe como un espejo natural
|
|
|
|
|
frame = cv2.flip(frame, 1)
|
|
|
|
|
display_frame = frame.copy()
|
|
|
|
|
|
|
|
|
|
# Usamos YuNet para garantizar que estamos capturando una cara válida
|
|
|
|
|
faces = detectar_rostros_yunet(frame)
|
|
|
|
|
mejor_rostro = None
|
|
|
|
|
max_area = 0
|
|
|
|
|
|
|
|
|
|
for (fx, fy, fw, fh, score) in faces:
|
|
|
|
|
area = fw * fh
|
|
|
|
|
cv2.rectangle(display_frame, (fx, fy), (fx+fw, fy+fh), (0, 255, 0), 2)
|
|
|
|
|
|
|
|
|
|
if area > max_area:
|
|
|
|
|
max_area = area
|
|
|
|
|
h_frame, w_frame = frame.shape[:2]
|
|
|
|
|
|
|
|
|
|
# Mismo margen del 30% que requiere MTCNN para alinear correctamente
|
|
|
|
|
m_x, m_y = int(fw * 0.30), int(fh * 0.30)
|
|
|
|
|
y1 = max(0, fy - m_y)
|
|
|
|
|
y2 = min(h_frame, fy + fh + m_y)
|
|
|
|
|
x1 = max(0, fx - m_x)
|
|
|
|
|
x2 = min(w_frame, fx + fw + m_x)
|
|
|
|
|
|
|
|
|
|
mejor_rostro = frame[y1:y2, x1:x2]
|
|
|
|
|
|
|
|
|
|
cv2.putText(display_frame, "Alineate y presiona [R]", (10, 30),
|
|
|
|
|
cv2.FONT_HERSHEY_SIMPLEX, 0.7, (0, 255, 255), 2)
|
|
|
|
|
cv2.imshow("Registro Webcam Local", display_frame)
|
|
|
|
|
|
|
|
|
|
key = cv2.waitKey(1) & 0xFF
|
|
|
|
|
if key == ord('q'):
|
|
|
|
|
break
|
|
|
|
|
elif key == ord('r'):
|
|
|
|
|
if mejor_rostro is not None and mejor_rostro.size > 0:
|
|
|
|
|
cv2.imshow("Captura Congelada", mejor_rostro)
|
|
|
|
|
cv2.waitKey(1)
|
|
|
|
|
|
|
|
|
|
print("\n--- NUEVO REGISTRO ---")
|
|
|
|
|
nom = input("Escribe el nombre exacto de la persona: ").strip()
|
|
|
|
|
|
|
|
|
|
if nom:
|
|
|
|
|
gen_input = input("¿Es Hombre (h) o Mujer (m)?: ").strip().lower()
|
|
|
|
|
genero_guardado = "Woman" if gen_input == 'm' else "Man"
|
|
|
|
|
|
|
|
|
|
# 1. Guardamos la foto pura
|
|
|
|
|
foto_path = os.path.join(DB_PATH, f"{nom}.jpg")
|
|
|
|
|
cv2.imwrite(foto_path, mejor_rostro)
|
|
|
|
|
|
|
|
|
|
# 2. Actualizamos el caché de géneros sin usar IA
|
|
|
|
|
ruta_generos = os.path.join(CACHE_PATH, "generos.json")
|
|
|
|
|
dic_generos = {}
|
|
|
|
|
if os.path.exists(ruta_generos):
|
|
|
|
|
try:
|
|
|
|
|
with open(ruta_generos, 'r') as f:
|
|
|
|
|
dic_generos = json.load(f)
|
|
|
|
|
except Exception: pass
|
|
|
|
|
|
|
|
|
|
dic_generos[nom] = genero_guardado
|
|
|
|
|
with open(ruta_generos, 'w') as f:
|
|
|
|
|
json.dump(dic_generos, f)
|
|
|
|
|
|
|
|
|
|
print(f"\n[OK] Foto guardada. Generando punto de gravedad matemático...")
|
|
|
|
|
|
|
|
|
|
# 3. Forzamos la creación del vector en la base de datos
|
|
|
|
|
gestionar_vectores(actualizar=True)
|
|
|
|
|
print(" Registro inyectado exitosamente en el sistema principal.")
|
|
|
|
|
|
|
|
|
|
else:
|
|
|
|
|
print("[!] Registro cancelado por nombre vacío.")
|
|
|
|
|
|
|
|
|
|
cv2.destroyWindow("Captura Congelada")
|
|
|
|
|
else:
|
|
|
|
|
print("[!] No se detectó ningún rostro claro. Acércate más a la luz.")
|
|
|
|
|
|
|
|
|
|
cap.release()
|
|
|
|
|
cv2.destroyAllWindows()
|
|
|
|
|
|
|
|
|
|
if __name__ == "__main__":
|
2026-03-30 17:11:49 +00:00
|
|
|
registrar_desde_webcam()
|