diff --git a/compair.py b/compair.py index 5da05b3..a48ea27 100644 --- a/compair.py +++ b/compair.py @@ -2,6 +2,7 @@ import face_recognition import cv2 import sys import os +import json import config @@ -16,20 +17,18 @@ except IndexError: sys.exit(1) user = sys.argv[1] -# Get a reference to webcam #0 (the default one) -video_capture = cv2.VideoCapture(config.device_id) - encodings = [] +tries = 0 try: - for exposure in ["L", "M", "S"]: - ref = face_recognition.load_image_file(os.path.dirname(__file__) + "/models/" + user + "/" + exposure + ".jpg") - enc = face_recognition.face_encodings(ref)[0] - encodings.append(enc) + encodings = json.load(open(os.path.dirname(__file__) + "/models/lem.dat")) except FileNotFoundError: stop(10) -tries = 0 +if len(encodings) < 3: + stop(1) + +video_capture = cv2.VideoCapture(config.device_id) while True: # Grab a single frame of video diff --git a/learn.py b/learn.py index c16aa88..2b1e3e8 100644 --- a/learn.py +++ b/learn.py @@ -1,29 +1,62 @@ +import face_recognition import subprocess import time import os +import sys +import json + +import config +import utils + +def captureFrame(delay): + subprocess.call(["fswebcam", "-S", str(delay), "--no-banner", "-d", "/dev/video" + str(config.device_id), tmp_file], stderr=open(os.devnull, "wb")) + + ref = face_recognition.load_image_file(tmp_file) + enc = face_recognition.face_encodings(ref) + + if len(enc) == 0: + print("No face detected, aborting") + sys.exit() + if len(enc) > 1: + print("Multiple faces detected, aborting") + sys.exit() + + clean_enc = [] + + for point in enc[0]: + clean_enc.append(point) + + encodings.append(clean_enc) user = os.environ.get("USER") +tmp_file = "/tmp/howdy_" + user + ".jpg" +enc_file = "./models/" + user + ".dat" +encodings = [] if not os.path.exists("models"): + print("No face model folder found, creating one") os.makedirs("models") -if not os.path.exists("models/" + user): - print("No face model folder found, creating one") - os.makedirs("models/" + user) +try: + encodings = json.load(open(enc_file)) +except FileNotFoundError: + encodings = False -print("Learning face for the user account " + os.environ.get("USER")) -print("Please look straigt into the camera for 5 seconds") +if encodings != False: + encodings = utils.print_menu(encodings) -time.sleep(2.5) +print("\nLearning face for the user account " + user) +print("Please look straight into the camera for 5 seconds") -subprocess.call(["fswebcam", "-S", "30", "--no-banner", "-d", "/dev/video1", "./models/" + user + "/L.jpg"], stderr=open(os.devnull, "wb")) +time.sleep(2) -time.sleep(.3) +for delay in [30, 6, 0]: + time.sleep(.3) + captureFrame(delay) -subprocess.call(["fswebcam", "-S", "6", "--no-banner", "-d", "/dev/video1", "./models/" + user + "/M.jpg"], stderr=open(os.devnull, "wb")) +with open(enc_file, "w") as datafile: + json.dump(encodings, datafile) -time.sleep(.3) - -subprocess.call(["fswebcam", "--no-banner", "-d", "/dev/video1", "./models/" + user + "/S.jpg"], stderr=open(os.devnull, "wb")) +os.remove(tmp_file) print("Done.") diff --git a/pam.py b/pam.py index 9018c36..a5b5ba5 100644 --- a/pam.py +++ b/pam.py @@ -3,10 +3,10 @@ import sys import os def doAuth(pamh): - status = subprocess.call(["python3", "/compair.py", pamh.get_user()]) + status = subprocess.call(["python3", os.path.dirname(__file__) + "/compair.py", pamh.get_user()]) if status == 10: - print("No face model is known for this user, aborting") + print("No face model is known for this user, skiping") return pamh.PAM_SYSTEM_ERR if status == 11: print("Timeout reached, ould not find a known face") @@ -15,7 +15,7 @@ def doAuth(pamh): print("Identified face as " + os.environ.get("USER")) return pamh.PAM_SUCCESS - print(status) + print("Unknown error: " + str(status)) return pamh.PAM_SYSTEM_ERR def pam_sm_authenticate(pamh, flags, args): diff --git a/utils.py b/utils.py new file mode 100644 index 0000000..1ed3ac4 --- /dev/null +++ b/utils.py @@ -0,0 +1,22 @@ +def print_menu(encodings): + if len(encodings) == 3: + print("There is 1 existing face model for this user") + else: + print("There are " + str(int(len(encodings) / 3)) + " existing face models for this user") + print("What do you want to do?\n") + + print("1: Add additional face model") + print("2: Overwrite older model(s)") + print("0: Exit") + + com = input("Option: ") + + if com == "1": + return encodings + elif com == "2": + return [] + elif com == "0": + sys.exit() + else: + print("Invalid option '" + com + "'\n") + return print_menu(encodings)