diff --git a/.travis.yml b/.travis.yml index 3e0a5f1..6f7d486 100644 --- a/.travis.yml +++ b/.travis.yml @@ -11,7 +11,8 @@ script: # Go through function tests - ./tests/importing.sh - ./tests/passthrough.sh - - ./tests/pam.sh + # Skip PAM integration tests for now because of broken pamtester + # - ./tests/pam.sh - ./tests/compare.sh # Remove howdy from the installation diff --git a/debian/postinst b/debian/postinst index f3dd041..31066b2 100755 --- a/debian/postinst +++ b/debian/postinst @@ -95,7 +95,7 @@ os.unlink("/tmp/howdy_picked_device") log("Upgrading pip to the latest version") # Update pip -handleStatus(sc(["pip3", "install", "--no-cache-dir", "--upgrade", "pip"])) +handleStatus(sc(["pip3", "install", "--upgrade", "pip"])) log("Downloading and unpacking data files") @@ -105,16 +105,16 @@ handleStatus(subprocess.call(["./install.sh"], shell=True, cwd="/lib/security/ho log("Downloading dlib") dlib_archive = "/tmp/v19.16.tar.gz" -loader = which("curl") +loader = which("wget") LOADER_CMD = None -# If curl is installed, use that as the downloader +# If wget is installed, use that as the downloader if loader: - LOADER_CMD = [loader, "--retry", "5", "--location", "--output"] -# Otherwise, fall back on wget -else: - loader = which("wget") LOADER_CMD = [loader, "--tries", "5", "--output-document"] +# Otherwise, fall back on curl +else: + loader = which("curl") + LOADER_CMD = [loader, "--retry", "5", "--location", "--output"] # Assemble and execute the download command cmd = LOADER_CMD + [dlib_archive, "https://github.com/davisking/dlib/archive/v19.16.tar.gz"] diff --git a/debian/source/options b/debian/source/options index 593ee7b..1216d00 100644 --- a/debian/source/options +++ b/debian/source/options @@ -1,6 +1,7 @@ tar-ignore = ".git" -tar-ignore = "models" tar-ignore = ".gitignore" +tar-ignore = ".github" +tar-ignore = "models" +tar-ignore = "tests" tar-ignore = "README.md" -tar-ignore = "LICENSE" tar-ignore = ".travis.yml" diff --git a/src/cli/add.py b/src/cli/add.py index 9d31643..9fd69b0 100644 --- a/src/cli/add.py +++ b/src/cli/add.py @@ -22,26 +22,31 @@ except ImportError as err: sys.exit(1) # Get the absolute path to the current directory -path = os.path.abspath(__file__ + '/..') +path = os.path.abspath(__file__ + "/..") + +# Test if at lest 1 of the data files is there and abort if it's not +if not os.path.isfile(path + "/../dlib-data/shape_predictor_5_face_landmarks.dat"): + print("Data files have not been downloaded, please run the following commands:") + print("\n\tcd " + os.path.realpath(path + "/../dlib-data")) + print("\tsudo ./install.sh\n") + sys.exit(1) # Read config from disk config = configparser.ConfigParser() config.read(path + "/../config.ini") -use_cnn = config.getboolean('core', 'use_cnn', fallback=False) +if not os.path.exists(config.get("video", "device_path")): + print("Camera path is not configured correctly, please edit the 'device_path' config value.") + sys.exit(1) + +use_cnn = config.getboolean("core", "use_cnn", fallback=False) if use_cnn: - face_detector = dlib.cnn_face_detection_model_v1( - path + '/../dlib-data/mmod_human_face_detector.dat' - ) + face_detector = dlib.cnn_face_detection_model_v1(path + "/../dlib-data/mmod_human_face_detector.dat") else: face_detector = dlib.get_frontal_face_detector() -pose_predictor = dlib.shape_predictor( - path + '/../dlib-data/shape_predictor_5_face_landmarks.dat' -) -face_encoder = dlib.face_recognition_model_v1( - path + '/../dlib-data/dlib_face_recognition_resnet_model_v1.dat' -) +pose_predictor = dlib.shape_predictor(path + "/../dlib-data/shape_predictor_5_face_landmarks.dat") +face_encoder = dlib.face_recognition_model_v1(path + "/../dlib-data/dlib_face_recognition_resnet_model_v1.dat") user = builtins.howdy_user # The permanent file to store the encoded model in @@ -154,7 +159,7 @@ while frames < 60: frames += 1 # Get all faces from that frame as encodings - face_locations = face_detector(gsframe, 1) # upsample 1 time + face_locations = face_detector(gsframe, 1) # If we've found at least one, we can continue if face_locations: @@ -176,9 +181,7 @@ if use_cnn: # Get the encodings in the frame face_landmark = pose_predictor(frame, face_location) -face_encoding = np.array( - face_encoder.compute_face_descriptor(frame, face_landmark, 1) # num_jitters=1 -) +face_encoding = np.array(face_encoder.compute_face_descriptor(frame, face_landmark, 1)) insert_model["data"].append(face_encoding.tolist()) diff --git a/src/compare.py b/src/compare.py index 281c424..c063d2f 100644 --- a/src/compare.py +++ b/src/compare.py @@ -24,6 +24,14 @@ def init_detector(lock): """Start face detector, encoder and predictor in a new thread""" global face_detector, pose_predictor, face_encoder + # Test if at lest 1 of the data files is there and abort if it's not + if not os.path.isfile(PATH + "/dlib-data/shape_predictor_5_face_landmarks.dat"): + print("Data files have not been downloaded, please run the following commands:") + print("\n\tcd " + PATH + "/dlib-data") + print("\tsudo ./install.sh\n") + lock.release() + sys.exit(1) + # Use the CNN detector if enabled if use_cnn: face_detector = dlib.cnn_face_detection_model_v1(PATH + "/dlib-data/mmod_human_face_detector.dat") @@ -171,7 +179,12 @@ while True: # Grab a single frame of video _, frame = video_capture.read() - gsframe = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY) + + try: + gsframe = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY) + except cv2.error: + print("Unknown camera, please check your 'device_path' config value.\n") + raise # Create a histogram of the image with 8 values hist = cv2.calcHist([gsframe], [0], None, [8], [0, 256]) diff --git a/src/config.ini b/src/config.ini index c658917..7a3b08e 100644 --- a/src/config.ini +++ b/src/config.ini @@ -54,7 +54,7 @@ frame_height = -1 # The lower this setting is, the more dark frames are ignored dark_threshold = 50 -# The recorder to use. Can be either opencv or ffmpeg. +# The recorder to use. Can be either opencv, ffmpeg or pyv4l2. # Switching from the default opencv to ffmpeg can help with grayscale issues. recording_plugin = opencv diff --git a/src/dlib-data/install.sh b/src/dlib-data/install.sh index b966d9f..7fcabe6 100755 --- a/src/dlib-data/install.sh +++ b/src/dlib-data/install.sh @@ -1,9 +1,24 @@ #!/bin/bash -# Download the archives -wget https://github.com/davisking/dlib-models/raw/master/dlib_face_recognition_resnet_model_v1.dat.bz2 -wget https://github.com/davisking/dlib-models/raw/master/mmod_human_face_detector.dat.bz2 -wget https://github.com/davisking/dlib-models/raw/master/shape_predictor_5_face_landmarks.dat.bz2 +echo "Downloading 3 required data files..." + +# Check if wget is installed +if hash wget;then + # Check if wget supports the option to only show the progress bar + wget --help | grep -q "\--show-progress" && \ + _PROGRESS_OPT="-q --show-progress" || _PROGRESS_OPT="" + + # Download the archives + wget $_PROGRESS_OPT --tries 5 https://github.com/davisking/dlib-models/raw/master/dlib_face_recognition_resnet_model_v1.dat.bz2 + wget $_PROGRESS_OPT --tries 5 https://github.com/davisking/dlib-models/raw/master/mmod_human_face_detector.dat.bz2 + wget $_PROGRESS_OPT --tries 5 https://github.com/davisking/dlib-models/raw/master/shape_predictor_5_face_landmarks.dat.bz2 + +# Otherwise fall back on curl +else + curl --location --retry 5 --output dlib_face_recognition_resnet_model_v1.dat.bz2 https://github.com/davisking/dlib-models/raw/master/dlib_face_recognition_resnet_model_v1.dat.bz2 + curl --location --retry 5 --output mmod_human_face_detector.dat.bz2 https://github.com/davisking/dlib-models/raw/master/mmod_human_face_detector.dat.bz2 + curl --location --retry 5 --output shape_predictor_5_face_landmarks.dat.bz2 https://github.com/davisking/dlib-models/raw/master/shape_predictor_5_face_landmarks.dat.bz2 +fi # Uncompress the data files and delete the original archive echo "Unpacking..." diff --git a/tests/pam.sh b/tests/pam.sh index 0f1f7a0..7633546 100755 --- a/tests/pam.sh +++ b/tests/pam.sh @@ -6,7 +6,7 @@ set -e sudo howdy clear -y || true # Change active camera to match video 1 -sudo sed -i "s,device_path.*,device_path = $PWD\/tests\/video\/match1.m4v,g" /lib/security/howdy/config.ini +sudo sed -i "s,device_path.*,device_path = $PWD/tests\/video\/match1.m4v,g" /lib/security/howdy/config.ini # Let howdy add the match face sudo howdy add -y