# 2: import cv2 import numpy as np import insightface from insightface.app import FaceAnalysis from insightface.utils import download_onnx from pathlib import Path from typing import Dict, List, Tuple import pickle import logging import os class FaceRecognitionSystem: def __init__(self, model_name: str = "buffalo_l", model_root: str = "./models"): # Set up logging logging.basicConfig(level=logging.INFO) self.logger = logging.getLogger(__name__) # Create model directory if it doesn't exist self.model_root = Path(model_root) self.model_root.mkdir(parents=True, exist_ok=True) # Set InsightFace model root # insightface.utils.set_download_root(str(self.model_root)) # insightface.utils.download(root='./models_x', sub_dir='downloads', name='file') # Initialize the face analysis model try: self.face_analyzer = FaceAnalysis( name=model_name, root=str(self.model_root), download=True # Allow downloading if model doesn't exist ) self.face_analyzer.prepare(ctx_id=-1, det_size=(640, 640)) # Using CPU self.logger.info(f"Face analyzer initialized successfully in {self.model_root}") except Exception as e: self.logger.error(f"Error initializing face analyzer: {e}") raise # Dictionary to store known face embeddings self.known_face_embeddings: Dict[str, np.ndarray] = {} def process_known_faces(self, people_folder_path: str) -> None: """Process and store embeddings of known faces from a folder.""" embeddings_file = self.model_root / "known_faces_embeddings.pkl" try: # Load existing embeddings if available if embeddings_file.exists(): with open(embeddings_file, 'rb') as f: self.known_face_embeddings = pickle.load(f) self.logger.info("Loaded existing face embeddings") return self.logger.info("Processing known faces...") people_path = Path(people_folder_path) if not people_path.exists(): self.logger.warning(f"Directory not found: {people_folder_path}") return for person_path in people_path.glob("*"): if person_path.is_dir(): person_name = person_path.name embeddings_list = [] for img_path in person_path.glob("*"): if img_path.suffix.lower() in ['.jpg', '.jpeg', '.png']: img = cv2.imread(str(img_path)) if img is None: self.logger.warning(f"Could not read image: {img_path}") continue faces = self.face_analyzer.get(img) if faces: embeddings_list.append(faces[0].embedding) else: self.logger.warning(f"No face detected in {img_path}") if embeddings_list: self.known_face_embeddings[person_name] = np.mean(embeddings_list, axis=0) self.logger.info(f"Processed {person_name}'s faces") else: self.logger.warning(f"No valid faces found for {person_name}") # Save embeddings in model directory with open(embeddings_file, 'wb') as f: pickle.dump(self.known_face_embeddings, f) self.logger.info(f"Face embeddings saved to {embeddings_file}") except Exception as e: self.logger.error(f"Error processing known faces: {e}") raise def identify_face(self, face_embedding: np.ndarray, threshold: float = 0.6) -> Tuple[str, float]: """Identify a face by comparing its embedding with known faces.""" try: best_match = "Unknown" best_score = float('inf') for person_name, known_embedding in self.known_face_embeddings.items(): similarity = np.dot(face_embedding, known_embedding) / ( np.linalg.norm(face_embedding) * np.linalg.norm(known_embedding) ) distance = 1 - similarity if distance < best_score: best_score = distance best_match = person_name return (best_match, best_score) if best_score < threshold else ("Unknown", best_score) except Exception as e: self.logger.error(f"Error in face identification: {e}") return ("Error", 1.0) def detect_and_identify(self, image_input) -> np.ndarray: """Detect and identify faces in an input image.""" try: # Handle both string paths and numpy arrays if isinstance(image_input, str): img = cv2.imread(image_input) else: img = image_input if img is None: raise ValueError("Could not read input image") faces = self.face_analyzer.get(img) for face in faces: bbox = face.bbox.astype(int) embedding = face.embedding name, score = self.identify_face(embedding) cv2.rectangle(img, (bbox[0], bbox[1]), (bbox[2], bbox[3]), (0, 255, 0), 2) label = f"{name} ({1-score:.2f})" cv2.putText(img, label.upper(), (bbox[0], bbox[1]-10), cv2.FONT_HERSHEY_PLAIN, 2.0, (0, 255, 0), 2) return img except Exception as e: self.logger.error(f"Error in detection and identification: {e}") raise # 1: # import cv2 # import numpy as np # import insightface # from insightface.app import FaceAnalysis # from pathlib import Path # from typing import Dict, List, Tuple # import pickle # import logging # class FaceRecognitionSystem: # def __init__(self, model_name: str = "buffalo_l"): # # Set up logging # logging.basicConfig(level=logging.INFO) # self.logger = logging.getLogger(__name__) # # Initialize the face analysis model # try: # self.face_analyzer = FaceAnalysis(name=model_name) # self.face_analyzer.prepare(ctx_id=-1, det_size=(640, 640)) # Using CPU # self.logger.info("Face analyzer initialized successfully") # except Exception as e: # self.logger.error(f"Error initializing face analyzer: {e}") # raise # # Dictionary to store known face embeddings # self.known_face_embeddings: Dict[str, np.ndarray] = {} # def process_known_faces(self, people_folder_path: str) -> None: # """Process and store embeddings of known faces from a folder.""" # embeddings_file = Path("known_faces_embeddings.pkl") # try: # # Load existing embeddings if available # if embeddings_file.exists(): # with open(embeddings_file, 'rb') as f: # self.known_face_embeddings = pickle.load(f) # self.logger.info("Loaded existing face embeddings") # return # self.logger.info("Processing known faces...") # people_path = Path(people_folder_path) # if not people_path.exists(): # self.logger.warning(f"Directory not found: {people_folder_path}") # return # for person_path in people_path.glob("*"): # if person_path.is_dir(): # person_name = person_path.name # embeddings_list = [] # for img_path in person_path.glob("*"): # if img_path.suffix.lower() in ['.jpg', '.jpeg', '.png']: # img = cv2.imread(str(img_path)) # if img is None: # self.logger.warning(f"Could not read image: {img_path}") # continue # faces = self.face_analyzer.get(img) # if faces: # embeddings_list.append(faces[0].embedding) # else: # self.logger.warning(f"No face detected in {img_path}") # if embeddings_list: # self.known_face_embeddings[person_name] = np.mean(embeddings_list, axis=0) # self.logger.info(f"Processed {person_name}'s faces") # else: # self.logger.warning(f"No valid faces found for {person_name}") # # Save embeddings # with open(embeddings_file, 'wb') as f: # pickle.dump(self.known_face_embeddings, f) # self.logger.info("Face processing complete") # except Exception as e: # self.logger.error(f"Error processing known faces: {e}") # raise # def identify_face(self, face_embedding: np.ndarray, threshold: float = 0.6) -> Tuple[str, float]: # """Identify a face by comparing its embedding with known faces.""" # try: # best_match = "Unknown" # best_score = float('inf') # for person_name, known_embedding in self.known_face_embeddings.items(): # similarity = np.dot(face_embedding, known_embedding) / ( # np.linalg.norm(face_embedding) * np.linalg.norm(known_embedding) # ) # distance = 1 - similarity # if distance < best_score: # best_score = distance # best_match = person_name # return (best_match, best_score) if best_score < threshold else ("Unknown", best_score) # except Exception as e: # self.logger.error(f"Error in face identification: {e}") # return ("Error", 1.0) # def detect_and_identify(self, image_input) -> np.ndarray: # """Detect and identify faces in an input image.""" # try: # # Handle both string paths and numpy arrays # if isinstance(image_input, str): # img = cv2.imread(image_input) # else: # img = image_input # if img is None: # raise ValueError("Could not read input image") # faces = self.face_analyzer.get(img) # for face in faces: # bbox = face.bbox.astype(int) # embedding = face.embedding # name, score = self.identify_face(embedding) # cv2.rectangle(img, (bbox[0], bbox[1]), (bbox[2], bbox[3]), (0, 255, 0), 2) # label = f"{name} ({1-score:.2f})" # cv2.putText(img, label.upper(), (bbox[0], bbox[1]-10), # cv2.FONT_HERSHEY_PLAIN, 2.0, (0, 255, 0), 2) # return img # except Exception as e: # self.logger.error(f"Error in detection and identification: {e}") # raise # OLD: # import cv2 # import numpy as np # import insightface # from insightface.app import FaceAnalysis # from insightface.data import get_image as ins_get_image # import os # from pathlib import Path # from typing import Dict, List, Tuple # import pickle # class FaceRecognitionSystem: # def __init__(self, model_name: str = "buffalo_l"): # # Initialize the face analysis model # self.face_analyzer = FaceAnalysis(name=model_name) # self.face_analyzer.prepare(ctx_id=0, det_size=(640, 640)) # # Dictionary to store known face embeddings # self.known_face_embeddings: Dict[str, np.ndarray] = {} # def process_known_faces(self, people_folder_path: str) -> None: # """Process and store embeddings of known faces from a folder.""" # # Create embeddings file path # # embeddings_file = Path("known_face_embeddings copy2.pkl") # embeddings_file = Path("data/model/known_faces_embeddings.pkl") # # Load existing embeddings if available # if embeddings_file.exists(): # with open(embeddings_file, 'rb') as f: # self.known_face_embeddings = pickle.load(f) # print("Loaded existing face embeddings.") # return # print("Processing known faces...") # for person_path in Path(people_folder_path).glob("*"): # if person_path.is_dir(): # person_name = person_path.name # embeddings_list = [] # # Process each image in person's folder # for img_path in person_path.glob("*"): # if img_path.suffix.lower() in ['.jpg', '.jpeg', '.png']: # img = cv2.imread(str(img_path)) # if img is None: # continue # # Get face embedding # faces = self.face_analyzer.get(img) # if faces: # embeddings_list.append(faces[0].embedding) # if embeddings_list: # # Average all embeddings for this person # self.known_face_embeddings[person_name] = np.mean(embeddings_list, axis=0) # print(f"Processed {person_name}'s faces") # # Save embeddings for future use # with open(embeddings_file, 'wb') as f: # pickle.dump(self.known_face_embeddings, f) # print("Face processing complete.") # # OLD: # def identify_face(self, face_embedding: np.ndarray, threshold: float = 0.6) -> Tuple[str, float]: # """Identify a face by comparing its embedding with known faces.""" # best_match = "Unknown" # best_score = float('inf') # for person_name, known_embedding in self.known_face_embeddings.items(): # # Calculate cosine similarity # similarity = np.dot(face_embedding, known_embedding) / ( # np.linalg.norm(face_embedding) * np.linalg.norm(known_embedding) # ) # distance = 1 - similarity # if distance < best_score: # best_score = distance # best_match = person_name # return (best_match, best_score) if best_score < threshold else ("Unknown", best_score) # def detect_and_identify(self, image_input, output_path: str = None) -> np.ndarray: # """Detect and identify faces in an input image.""" # # Handle both string paths and numpy arrays # if isinstance(image_input, str): # img = cv2.imread(image_input) # else: # img = image_input # if img is None: # raise ValueError("Could not read input image") # # Rest of the code remains the same # faces = self.face_analyzer.get(img) # for face in faces: # bbox = face.bbox.astype(int) # embedding = face.embedding # name, score = self.identify_face(embedding) # cv2.rectangle(img, (bbox[0], bbox[1]), (bbox[2], bbox[3]), (0, 255, 0), 2) # label = f"{name} ({1-score:.2f})" # cv2.putText(img, label.upper(), (bbox[0], bbox[1]-10), # cv2.FONT_HERSHEY_PLAIN, 4.2, (0, 255, 0), 2) # # cv2.FONT_HERSHEY_SIMPLEX, 0.6, (0, 255, 0), 2) # if output_path: # cv2.imwrite(output_path, img) # return img # # def detect_and_identify(self, image_path: str, output_path: str = None) -> np.ndarray: # # """Detect and identify faces in an input image.""" # # # Read input image # # img = cv2.imread(image_path) # # if img is None: # # raise ValueError("Could not read input image") # # # Detect faces # # faces = self.face_analyzer.get(img) # # # Draw results on image # # for face in faces: # # bbox = face.bbox.astype(int) # # embedding = face.embedding # # name, score = self.identify_face(embedding) # # # Draw rectangle around face # # cv2.rectangle(img, (bbox[0], bbox[1]), (bbox[2], bbox[3]), (0, 255, 0), 2) # # # Add name and confidence score # # label = f"{name} ({1-score:.2f})" # # cv2.putText(img, label, (bbox[0], bbox[1]-10), # # cv2.FONT_HERSHEY_PLAIN, 1.5, (0, 255, 0), 2) # # # Save output image if path provided # # if output_path: # # cv2.imwrite(output_path, img) # # return img