dreamlessx commited on
Commit
5be749f
·
verified ·
1 Parent(s): e3a75a0

Update landmarkdiff/face_verifier.py to v0.3.2

Browse files
Files changed (1) hide show
  1. landmarkdiff/face_verifier.py +16 -9
landmarkdiff/face_verifier.py CHANGED
@@ -15,6 +15,7 @@ Designed for:
15
 
16
  from __future__ import annotations
17
 
 
18
  from dataclasses import dataclass, field
19
  from pathlib import Path
20
  from typing import Any
@@ -22,6 +23,8 @@ from typing import Any
22
  import cv2
23
  import numpy as np
24
 
 
 
25
  # ---------------------------------------------------------------------------
26
  # Data structures
27
  # ---------------------------------------------------------------------------
@@ -706,7 +709,11 @@ def get_face_embedding(image: np.ndarray) -> np.ndarray | None:
706
  try:
707
  faces = app.get(image)
708
  if faces:
709
- return faces[0].embedding
 
 
 
 
710
  except Exception:
711
  pass
712
  return None
@@ -715,12 +722,12 @@ def get_face_embedding(image: np.ndarray) -> np.ndarray | None:
715
  def verify_identity(
716
  original: np.ndarray,
717
  restored: np.ndarray,
718
- threshold: float = 0.6,
719
  ) -> tuple[float, bool]:
720
  """Compare identity between original and restored using ArcFace.
721
 
722
  Returns (cosine_similarity, passed).
723
- Similarity > threshold means same person (threshold=0.6 is conservative).
724
  """
725
  emb_orig = get_face_embedding(original)
726
  emb_rest = get_face_embedding(restored)
@@ -743,11 +750,11 @@ def verify_identity(
743
  def verify_and_restore(
744
  image: np.ndarray,
745
  quality_threshold: float = 60.0,
746
- identity_threshold: float = 0.6,
747
  restore_mode: str = "auto",
748
  codeformer_fidelity: float = 0.7,
749
  ) -> RestorationResult:
750
- """Full pipeline: analyze restore verify identity.
751
 
752
  This is the main entry point for the face verifier. It:
753
  1. Analyzes the input for distortions
@@ -830,7 +837,7 @@ def verify_batch(
830
  image_dir: str,
831
  output_dir: str | None = None,
832
  quality_threshold: float = 60.0,
833
- identity_threshold: float = 0.6,
834
  restore_mode: str = "auto",
835
  save_rejected: bool = False,
836
  extensions: tuple[str, ...] = (".jpg", ".jpeg", ".png", ".webp", ".bmp"),
@@ -882,7 +889,7 @@ def verify_batch(
882
 
883
  for i, img_file in enumerate(image_files):
884
  if (i + 1) % 50 == 0 or i == 0:
885
- print(f"Processing {i + 1}/{len(image_files)}: {img_file.name}")
886
 
887
  image = cv2.imread(str(img_file))
888
  if image is None:
@@ -934,7 +941,7 @@ def verify_batch(
934
  # Save report
935
  report_text = report.summary()
936
  (out_path / "report.txt").write_text(report_text)
937
- print(f"\n{report_text}")
938
- print(f"\nResults saved to {out_path}/")
939
 
940
  return report
 
15
 
16
  from __future__ import annotations
17
 
18
+ import logging
19
  from dataclasses import dataclass, field
20
  from pathlib import Path
21
  from typing import Any
 
23
  import cv2
24
  import numpy as np
25
 
26
+ logger = logging.getLogger(__name__)
27
+
28
  # ---------------------------------------------------------------------------
29
  # Data structures
30
  # ---------------------------------------------------------------------------
 
709
  try:
710
  faces = app.get(image)
711
  if faces:
712
+ emb = faces[0].embedding
713
+ if np.linalg.norm(emb) < 1e-6:
714
+ logger.warning("ArcFace returned near-zero embedding (occluded face?)")
715
+ return None
716
+ return emb
717
  except Exception:
718
  pass
719
  return None
 
722
  def verify_identity(
723
  original: np.ndarray,
724
  restored: np.ndarray,
725
+ threshold: float = 0.5,
726
  ) -> tuple[float, bool]:
727
  """Compare identity between original and restored using ArcFace.
728
 
729
  Returns (cosine_similarity, passed).
730
+ Similarity > threshold means same person (0.5 accommodates non-frontal poses).
731
  """
732
  emb_orig = get_face_embedding(original)
733
  emb_rest = get_face_embedding(restored)
 
750
  def verify_and_restore(
751
  image: np.ndarray,
752
  quality_threshold: float = 60.0,
753
+ identity_threshold: float = 0.5,
754
  restore_mode: str = "auto",
755
  codeformer_fidelity: float = 0.7,
756
  ) -> RestorationResult:
757
+ """Full pipeline: analyze -> restore -> verify identity.
758
 
759
  This is the main entry point for the face verifier. It:
760
  1. Analyzes the input for distortions
 
837
  image_dir: str,
838
  output_dir: str | None = None,
839
  quality_threshold: float = 60.0,
840
+ identity_threshold: float = 0.5,
841
  restore_mode: str = "auto",
842
  save_rejected: bool = False,
843
  extensions: tuple[str, ...] = (".jpg", ".jpeg", ".png", ".webp", ".bmp"),
 
889
 
890
  for i, img_file in enumerate(image_files):
891
  if (i + 1) % 50 == 0 or i == 0:
892
+ logger.info("Processing %d/%d: %s", i + 1, len(image_files), img_file.name)
893
 
894
  image = cv2.imread(str(img_file))
895
  if image is None:
 
941
  # Save report
942
  report_text = report.summary()
943
  (out_path / "report.txt").write_text(report_text)
944
+ logger.info("\n%s", report_text)
945
+ logger.info("Results saved to %s/", out_path)
946
 
947
  return report