Commit 04489fd1 authored by Kyle Anderson's avatar Kyle Anderson

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.
parent 9505915c
......@@ -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,
......
......@@ -3,7 +3,6 @@ import time
import cv2
from imutils.video import VideoStream
USER_IDS_KEY = "user_ids"
DATABASE_LOC = "./dataset/faces.pickle"
......
"""
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)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment