2025-07-02 18:52:28 +09:00
|
|
|
import argparse
|
2025-11-08 01:15:25 +09:00
|
|
|
|
|
|
|
|
import cv2
|
2025-07-02 18:52:28 +09:00
|
|
|
import numpy as np
|
|
|
|
|
|
ref: Add comprehensive test suite and enhance model functionality
- Add new test files for age_gender, factory, landmark, recognition, scrfd, and utils
- Add new scripts for age_gender, landmarks, and video detection
- Update documentation in README.md, MODELS.md, QUICKSTART.md
- Improve model constants and face utilities
- Update detection models (retinaface, scrfd) with enhanced functionality
- Update project configuration in pyproject.toml
2025-11-15 21:09:37 +09:00
|
|
|
from uniface.detection import RetinaFace, SCRFD
|
2025-07-02 18:52:28 +09:00
|
|
|
from uniface.face_utils import compute_similarity
|
ref: Add comprehensive test suite and enhance model functionality
- Add new test files for age_gender, factory, landmark, recognition, scrfd, and utils
- Add new scripts for age_gender, landmarks, and video detection
- Update documentation in README.md, MODELS.md, QUICKSTART.md
- Improve model constants and face utilities
- Update detection models (retinaface, scrfd) with enhanced functionality
- Update project configuration in pyproject.toml
2025-11-15 21:09:37 +09:00
|
|
|
from uniface.recognition import ArcFace, MobileFace, SphereFace
|
2025-07-02 18:52:28 +09:00
|
|
|
|
|
|
|
|
|
|
|
|
|
def extract_reference_embedding(detector, recognizer, image_path: str) -> np.ndarray:
|
|
|
|
|
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
|
2025-11-08 01:15:25 +09:00
|
|
|
landmarks = np.array(faces[0]["landmarks"])
|
|
|
|
|
|
2025-07-02 18:52:28 +09:00
|
|
|
# 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):
|
|
|
|
|
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
|
2025-11-08 01:15:25 +09:00
|
|
|
bbox = face["bbox"]
|
|
|
|
|
landmarks = np.array(face["landmarks"])
|
|
|
|
|
|
2025-07-02 18:52:28 +09:00
|
|
|
x1, y1, x2, y2 = map(int, bbox)
|
2025-11-08 01:15:25 +09:00
|
|
|
|
2025-07-02 18:52:28 +09:00
|
|
|
# Get the normalized embedding for the current face
|
|
|
|
|
embedding = recognizer.get_normalized_embedding(frame, landmarks)
|
2025-11-08 01:15:25 +09:00
|
|
|
|
2025-07-02 18:52:28 +09:00
|
|
|
# Compare with the reference embedding
|
|
|
|
|
sim = compute_similarity(ref_embedding, embedding)
|
2025-11-08 01:15:25 +09:00
|
|
|
|
2025-07-02 18:52:28 +09:00
|
|
|
# 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)
|
2025-11-08 01:15:25 +09:00
|
|
|
if cv2.waitKey(1) & 0xFF == ord("q"):
|
2025-07-02 18:52:28 +09:00
|
|
|
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(
|
2025-11-08 01:15:25 +09:00
|
|
|
"--detector", type=str, default="scrfd", choices=["retinaface", "scrfd"], help="Face detection method."
|
2025-07-02 18:52:28 +09:00
|
|
|
)
|
|
|
|
|
parser.add_argument(
|
|
|
|
|
"--recognizer",
|
|
|
|
|
type=str,
|
|
|
|
|
default="arcface",
|
2025-11-08 01:15:25 +09:00
|
|
|
choices=["arcface", "mobileface", "sphereface"],
|
|
|
|
|
help="Face recognition method.",
|
2025-07-02 18:52:28 +09:00
|
|
|
)
|
2025-11-08 01:15:25 +09:00
|
|
|
parser.add_argument("--verbose", action="store_true", help="Enable verbose logging")
|
2025-07-02 18:52:28 +09:00
|
|
|
args = parser.parse_args()
|
|
|
|
|
|
2025-11-08 01:15:25 +09:00
|
|
|
if args.verbose:
|
|
|
|
|
from uniface import enable_logging
|
|
|
|
|
|
|
|
|
|
enable_logging()
|
|
|
|
|
|
2025-07-02 18:52:28 +09:00
|
|
|
print("Initializing models...")
|
ref: Add comprehensive test suite and enhance model functionality
- Add new test files for age_gender, factory, landmark, recognition, scrfd, and utils
- Add new scripts for age_gender, landmarks, and video detection
- Update documentation in README.md, MODELS.md, QUICKSTART.md
- Improve model constants and face utilities
- Update detection models (retinaface, scrfd) with enhanced functionality
- Update project configuration in pyproject.toml
2025-11-15 21:09:37 +09:00
|
|
|
if args.detector == 'retinaface':
|
|
|
|
|
detector = RetinaFace()
|
|
|
|
|
else:
|
|
|
|
|
detector = SCRFD()
|
|
|
|
|
|
|
|
|
|
if args.recognizer == 'arcface':
|
|
|
|
|
recognizer = ArcFace()
|
|
|
|
|
elif args.recognizer == 'mobileface':
|
|
|
|
|
recognizer = MobileFace()
|
|
|
|
|
else:
|
|
|
|
|
recognizer = SphereFace()
|
2025-11-08 01:15:25 +09:00
|
|
|
|
2025-07-02 18:52:28 +09:00
|
|
|
print("Extracting reference embedding...")
|
|
|
|
|
ref_embedding = extract_reference_embedding(detector, recognizer, args.image)
|
2025-11-08 01:15:25 +09:00
|
|
|
|
2025-07-02 18:52:28 +09:00
|
|
|
run_video(detector, recognizer, ref_embedding)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if __name__ == "__main__":
|
2025-11-08 01:15:25 +09:00
|
|
|
main()
|