From 04489fd14dd7550c0ea4437304b9e64b017323b5 Mon Sep 17 00:00:00 2001 From: Kyle Anderson Date: Tue, 29 Oct 2019 10:55:35 -0400 Subject: [PATCH] Working register + authenticate user The registering and authentication of users now works together nicely. Will continue with making it more efficient and integration with the react side. --- authenticate_user.py | 53 ++++++++++++++++++++++---------------------- common.py | 1 - register_user.py | 16 +++++++------ 3 files changed, 35 insertions(+), 35 deletions(-) diff --git a/authenticate_user.py b/authenticate_user.py index 260e1fc..0edc476 100644 --- a/authenticate_user.py +++ b/authenticate_user.py @@ -2,11 +2,11 @@ Methods for authenticating a user. """ -from imutils.video import VideoStream -import face_recognition -import imutils import time + import cv2 +import face_recognition +import imutils import common from data_handler import load_database @@ -24,23 +24,20 @@ def load_encodings(file_location: str): def determine_identity(face_encoding, known_faces): - """Determines the most likely identity of a single face. Returns the user id.""" - matches = face_recognition.compare_faces( - known_faces["encodings"], face_encoding) - matched_user = '' - matched_user_id_count = {} - - # If there is at least one match to a face in the database, figure out which one it is. - if True in matches: - matched_users = [user_index for ( - user_index, is_match) in enumerate(matches) if is_match] - - for i in matched_users: - user_id: str = known_faces[USER_IDS_KEY][i] - matched_user_id_count[user_id] = matched_user_id_count.get(user_id, 0) + 1 - - matched_user: str = max(matched_user_id_count, - key=matched_user_id_count.get) + """ + "Determines the most likely identity of a single face. Returns the user id. + :param face_encoding: The encoding which needs identification. + :param known_faces: The database of known faces to use for searching. + :return: The string user_id of the recognized user. + """ + recognized_users = {} + for (user_id, user_encodings) in known_faces.items(): + matches = face_recognition.compare_faces(user_encodings, face_encoding) + # Count the number of occurrences of true. + recognized_users[user_id] = matches.count(True) + + matched_user: str = max(recognized_users, + key=recognized_users.get) return matched_user @@ -54,10 +51,10 @@ def check_recognized_users(recognized_user_counts): return recognized_users -def draw_rectanges_and_user_ids(image_frame, conversion: float, boxes, user_ids: list): +def draw_rectanges_and_user_ids(image_frame, conversion: float, box_user_id_map: dict): """Draws the rectangles and user_ids onto the video stream so anyone viewing the stream could see them.""" - if boxes and user_ids and len(user_ids) > 0: - for ((top, right, bottom, left), user_id) in zip(boxes, user_ids): + if box_user_id_map and len(box_user_id_map) > 0: + for ((top, right, bottom, left), user_id) in box_user_id_map.items(): top = round(top * conversion) right = round(right * conversion) bottom = round(bottom * conversion) @@ -98,25 +95,27 @@ def recognize_user(known_faces: dict, encoding_model: str = "hog", image_flip: i # Detect the location of each face and determine the boxes in which they lie boxes = face_recognition.face_locations( rgb_image, model=encoding_model) - # Computer the facial embeddings (the encoding) at + # Compute the facial embeddings (the encoding) at # each of the locations found in the previous line. encodings = face_recognition.face_encodings(rgb_image, boxes) - for encoding in encodings: + box_user_id_mapping = {} + for (i, encoding) in enumerate(encodings): user_id: str = determine_identity(encoding, known_faces) if user_id: if user_id not in recognized_users_count: recognized_users_count[user_id] = 0 recognized_users_count[user_id] += 1 + box_user_id_mapping[boxes[i]] = user_id if draw_rectangles: - draw_rectanges_and_user_ids(image_frame, r, boxes, list(known_faces[USER_IDS_KEY])) + draw_rectanges_and_user_ids(image_frame, r, box_user_id_mapping) # Now check if we have already positively identified a user enough times recognized_users = check_recognized_users(recognized_users_count) if len(recognized_users) > 0: break - cv2.waitKey(1) # Required or else video stream doesn't really render. + cv2.waitKey(20) # Required or else video stream doesn't really render. if recognized_users_count: recognized_user = max(recognized_users_count, diff --git a/common.py b/common.py index 8c1eee5..e6c02f9 100644 --- a/common.py +++ b/common.py @@ -3,7 +3,6 @@ import time import cv2 from imutils.video import VideoStream -USER_IDS_KEY = "user_ids" DATABASE_LOC = "./dataset/faces.pickle" diff --git a/register_user.py b/register_user.py index 6afed8c..5fabc74 100644 --- a/register_user.py +++ b/register_user.py @@ -1,12 +1,13 @@ """ Creates a facial recognition profile for a new user. """ +import os + +import cv2 +import face_recognition + import common import data_handler -from common import USER_IDS_KEY, start_video_stream -import face_recognition -import cv2 -import os def process_image(image, encoding_model: str = "hog"): @@ -21,7 +22,8 @@ def process_image(image, encoding_model: str = "hog"): # Detect the coordinates of the boxes corresponding to faces in the input image boxes = face_recognition.face_locations(image_rgb, model=encoding_model) # Actually make the encodings for the face. - return face_recognition.face_encodings(image_rgb, boxes) + # Only want the first recognized face + return face_recognition.face_encodings(image_rgb, [boxes[0]]) if boxes and len(boxes) > 0 else [] def register_user(user_id: str, dataset_dir: str, encoding_model="hog", database_loc: str = common.DATABASE_LOC, @@ -41,11 +43,11 @@ def register_user(user_id: str, dataset_dir: str, encoding_model="hog", database # Might want to check file validity here at some point, but won't for now. image = cv2.imread(full_path) if image is not None: - processed = process_image(image, encoding_model=encoding_model) if show_output: print(f"Processing image {i + 1}") + processed = process_image(image, encoding_model=encoding_model) if processed: - processed_images.append(processed) + processed_images.extend(processed) if len(processed_images) > 0: # Only do things if we actually have stuff to add. user_info = data_handler.load_database(database_loc) -- GitLab