diff --git a/compare.py b/compare.py index 8d0e33f..a3b53e2 100644 --- a/compare.py +++ b/compare.py @@ -2,13 +2,21 @@ # Running in a local python instance to get around PATH issues # Import required modules -import face_recognition import cv2 import sys import os import json +import time +import math import configparser +# Start timing +timings = [time.time()] + +# Import face recognition, takes some time +import face_recognition +timings.append(time.time()) + # Read config from disk config = configparser.ConfigParser() config.read(os.path.dirname(os.path.abspath(__file__)) + "/config.ini") @@ -27,26 +35,38 @@ except IndexError: # The username of the authenticating user user = sys.argv[1] -# List of known faces, encoded by face_recognition +# The model file contents +models = [] +# Encoded face models encodings = [] # Amount of frames already matched tries = 0 # Try to load the face model from the models folder try: - encodings = json.load(open(os.path.dirname(os.path.abspath(__file__)) + "/models/" + user + ".dat")) + models = json.load(open(os.path.dirname(os.path.abspath(__file__)) + "/models/" + user + ".dat")) except FileNotFoundError: sys.exit(10) -# Verify that we have a valid model file -if len(encodings) < 3: - sys.exit(1) +# Check if the file contains a model +if len(models) < 1: + sys.exit(10) + +# Put all models together into 1 array +for model in models: + encodings += model["data"] # Start video capture on the IR camera video_capture = cv2.VideoCapture(int(config.get("video", "device_id"))) +timings.append(time.time()) +# Start the read loop +frames = 0 while True: + frames += 1 + # Grab a single frame of video + # Don't remove ret, it doesn't work without it ret, frame = video_capture.read() # Get all faces from that frame as encodings @@ -58,8 +78,32 @@ while True: matches = face_recognition.face_distance(encodings, face_encoding) # Check if any match is certain enough to be the user we're looking for + match_index = 0 for match in matches: - if match < int(config.get("video", "certainty")) and match > 0: + match_index += 1 + + # Try to find a match that's confident enough + if match * 10 < float(config.get("video", "certainty")) and match > 0: + timings.append(time.time()) + + # If set to true in the config, print debug text + if config.get("debug", "end_report") == "true": + print("DEBUG END REPORT\n") + + print("Time spend") + print(" Importing face_recognition: " + str(round((timings[1] - timings[0]) * 1000)) + "ms") + print(" Opening the camera: " + str(round((timings[2] - timings[1]) * 1000)) + "ms") + print(" Searching for known face: " + str(round((timings[3] - timings[2]) * 1000)) + "ms\n") + + print("Frames searched: " + str(frames)) + print("Certainty winning frame: " + str(round(match * 10, 3))) + + exposures = ["long", "medium", "short"] + model_id = math.floor(float(match_index) / 3) + + print("Winning model: " + str(model_id) + " (\"" + models[model_id]["label"] + "\") using " + exposures[match_index % 3] + " exposure\n") + + # End peacegully stop(0) # Stop if we've exceded the maximum retry count diff --git a/config.ini b/config.ini index cd4819c..428b68f 100644 --- a/config.ini +++ b/config.ini @@ -9,11 +9,15 @@ suppress_unknown = false [video] # The certainty of the detected face belonging to the user of the account # On a scale from 1 to 10, values above 5 are not recommended -certainty = 3 +certainty = 3.5 # The number of frames to capture and to process before timing out frame_count = 30 # The /dev/videoX id to capture frames from -# In my case, video0 is the normal camera and video1 is the IR version +# Should be set automatically by the installer device_id = 1 + +[debug] +# Show a short but detailed diagnostic report in console +end_report = false