import argparse import cv2 import numpy as np # Use the new high-level factory functions from uniface.detection import create_detector from uniface.face_utils import compute_similarity from uniface.recognition import create_recognizer def extract_reference_embedding(detector, recognizer, image_path: str) -> np.ndarray: """Extracts a normalized embedding from the first face found in an image.""" image = cv2.imread(image_path) if image is None: raise RuntimeError(f"Failed to load image: {image_path}") faces = detector.detect(image) if not faces: raise RuntimeError("No faces found in reference image.") # Get landmarks from the first detected face dictionary landmarks = np.array(faces[0]["landmarks"]) # Use normalized embedding for more reliable similarity comparison embedding = recognizer.get_normalized_embedding(image, landmarks) return embedding def run_video(detector, recognizer, ref_embedding: np.ndarray, threshold: float = 0.4): """Run real-time face recognition from a webcam feed.""" cap = cv2.VideoCapture(0) if not cap.isOpened(): raise RuntimeError("Webcam could not be opened.") print("Webcam started. Press 'q' to quit.") while True: ret, frame = cap.read() if not ret: break faces = detector.detect(frame) # Loop through each detected face for face in faces: # Extract bbox and landmarks from the dictionary bbox = face["bbox"] landmarks = np.array(face["landmarks"]) x1, y1, x2, y2 = map(int, bbox) # Get the normalized embedding for the current face embedding = recognizer.get_normalized_embedding(frame, landmarks) # Compare with the reference embedding sim = compute_similarity(ref_embedding, embedding) # Draw results label = f"Match ({sim:.2f})" if sim > threshold else f"Unknown ({sim:.2f})" color = (0, 255, 0) if sim > threshold else (0, 0, 255) cv2.rectangle(frame, (x1, y1), (x2, y2), color, 2) cv2.putText(frame, label, (x1, y1 - 10), cv2.FONT_HERSHEY_SIMPLEX, 0.6, color, 2) cv2.imshow("Face Recognition", frame) if cv2.waitKey(1) & 0xFF == ord("q"): break cap.release() cv2.destroyAllWindows() def main(): parser = argparse.ArgumentParser(description="Face recognition using a reference image.") parser.add_argument("--image", type=str, required=True, help="Path to the reference face image.") parser.add_argument( "--detector", type=str, default="scrfd", choices=["retinaface", "scrfd"], help="Face detection method." ) parser.add_argument( "--recognizer", type=str, default="arcface", choices=["arcface", "mobileface", "sphereface"], help="Face recognition method.", ) parser.add_argument("--verbose", action="store_true", help="Enable verbose logging") args = parser.parse_args() if args.verbose: from uniface import enable_logging enable_logging() print("Initializing models...") detector = create_detector(method=args.detector) recognizer = create_recognizer(method=args.recognizer) print("Extracting reference embedding...") ref_embedding = extract_reference_embedding(detector, recognizer, args.image) run_video(detector, recognizer, ref_embedding) if __name__ == "__main__": main()