02-ago: [proyecto] vigilancia - alineacion facial ArcFace (landmarks YuNet) + consenso 3 frames en alerta + enroll sin rellenar nombres fantasma. Prueba 45s: INES reconocida 80% frames
This commit is contained in:
@@ -35,9 +35,9 @@ def capturar_cuerpo(r, frame):
|
|||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
nombres = sys.argv[1:3]
|
nombres = sys.argv[1:]
|
||||||
while len(nombres) < 2:
|
if not nombres:
|
||||||
nombres.append(f"Hija{len(nombres) + 1}")
|
nombres = ["Hija1", "Hija2"]
|
||||||
print(f"Registrando: {nombres}")
|
print(f"Registrando: {nombres}")
|
||||||
|
|
||||||
r = rec.cargar_reconocedor()
|
r = rec.cargar_reconocedor()
|
||||||
@@ -102,6 +102,9 @@ def main():
|
|||||||
cv2.imwrite(os.path.join(carpeta, "cara_ref.jpg"),
|
cv2.imwrite(os.path.join(carpeta, "cara_ref.jpg"),
|
||||||
frame[max(0, y - 20):y + h + 20, max(0, x - 20):x + w + 20])
|
frame[max(0, y - 20):y + h + 20, max(0, x - 20):x + w + 20])
|
||||||
print(f" Cara de {nombre} registrada (score {caja[-1]:.2f})")
|
print(f" Cara de {nombre} registrada (score {caja[-1]:.2f})")
|
||||||
|
if os.path.exists(os.path.join(carpeta, "body.npy")):
|
||||||
|
print(f" {nombre} ya tenia cuerpo; registro completado.")
|
||||||
|
break
|
||||||
fase = "cuerpo"
|
fase = "cuerpo"
|
||||||
|
|
||||||
elif fase == "cuerpo" and tecla == ord("b"):
|
elif fase == "cuerpo" and tecla == ord("b"):
|
||||||
|
|||||||
@@ -131,7 +131,13 @@ def main():
|
|||||||
texto = f"🚨 Presencia en {cam.nombre} - {ts}"
|
texto = f"🚨 Presencia en {cam.nombre} - {ts}"
|
||||||
if ident is not None:
|
if ident is not None:
|
||||||
try:
|
try:
|
||||||
resultados = ident.analizar_frame(frame)
|
resultados = []
|
||||||
|
for _ in range(3):
|
||||||
|
f2 = cam.leer_frame()
|
||||||
|
if f2 is None:
|
||||||
|
continue
|
||||||
|
resultados += ident.analizar_frame(f2)
|
||||||
|
time.sleep(0.1)
|
||||||
if resultados:
|
if resultados:
|
||||||
texto = componer_alerta(resultados, cam.nombre, ts)
|
texto = componer_alerta(resultados, cam.nombre, ts)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
|
|||||||
@@ -69,19 +69,48 @@ class Reconocedor:
|
|||||||
return [c for c in caras if c[-1] >= 0.6]
|
return [c for c in caras if c[-1] >= 0.6]
|
||||||
|
|
||||||
def embedding_cara(self, frame, caja):
|
def embedding_cara(self, frame, caja):
|
||||||
x, y, w, h = (int(v) for v in caja[:4])
|
alineada = self._alinear_cara(frame, caja)
|
||||||
x, y = max(0, x), max(0, y)
|
if alineada is None:
|
||||||
recorte = frame[y:y + h, x:x + w]
|
|
||||||
if recorte.size == 0:
|
|
||||||
return None
|
return None
|
||||||
blob = cv2.dnn.blobFromImage(
|
blob = cv2.dnn.blobFromImage(
|
||||||
recorte, 1.0 / 128, (112, 112), (127.5, 127.5, 127.5), swapRB=True
|
alineada, 1.0 / 128, (112, 112), (127.5, 127.5, 127.5), swapRB=True
|
||||||
)
|
)
|
||||||
self.arcface.setInput(blob)
|
self.arcface.setInput(blob)
|
||||||
emb = self.arcface.forward().flatten()
|
emb = self.arcface.forward().flatten()
|
||||||
norm = np.linalg.norm(emb)
|
norm = np.linalg.norm(emb)
|
||||||
return emb / norm if norm > 0 else None
|
return emb / norm if norm > 0 else None
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def _alinear_cara(frame, caja):
|
||||||
|
"""Alinea el rostro con los landmarks (ArcFace espera 112x112 alineado)."""
|
||||||
|
if len(caja) < 15:
|
||||||
|
return None
|
||||||
|
pts = caja[4:14].reshape(5, 2)
|
||||||
|
if pts.min() < 0:
|
||||||
|
return None
|
||||||
|
# Template estandar de ArcFace (112x112)
|
||||||
|
dst = np.array([
|
||||||
|
[38.2946, 51.6963],
|
||||||
|
[73.5318, 51.5014],
|
||||||
|
[56.0252, 71.7366],
|
||||||
|
[41.5493, 92.3655],
|
||||||
|
[70.7299, 92.2041],
|
||||||
|
], dtype=np.float32)
|
||||||
|
# Orden YuNet: ojo der, ojo izq, nariz, comisura der, comisura izq
|
||||||
|
src = np.array([
|
||||||
|
pts[1], pts[0], pts[2], pts[4], pts[3],
|
||||||
|
], dtype=np.float32)
|
||||||
|
try:
|
||||||
|
M, _ = cv2.estimateAffinePartial2D(src, dst, method=cv2.LMEDS)
|
||||||
|
except Exception:
|
||||||
|
return None
|
||||||
|
if M is None:
|
||||||
|
return None
|
||||||
|
alineada = cv2.warpAffine(
|
||||||
|
frame, M, (112, 112), borderValue=0.0
|
||||||
|
)
|
||||||
|
return alineada
|
||||||
|
|
||||||
# ------------------------------------------------------------------
|
# ------------------------------------------------------------------
|
||||||
# Cuerpo
|
# Cuerpo
|
||||||
# ------------------------------------------------------------------
|
# ------------------------------------------------------------------
|
||||||
|
|||||||
Reference in New Issue
Block a user