mirror of
https://github.com/boltgolt/howdy.git
synced 2024-09-19 09:51:19 +02:00
Implemented conversations and better config
This commit is contained in:
parent
542549934b
commit
7b9db83ad0
6 changed files with 45 additions and 28 deletions
3
.gitignore
vendored
3
.gitignore
vendored
|
@ -102,6 +102,3 @@ ENV/
|
|||
|
||||
# generated models
|
||||
/models
|
||||
|
||||
# config file
|
||||
config.py
|
||||
|
|
|
@ -12,7 +12,7 @@ sudo apt install libpam-python fswebcam libopencv-dev python-opencv
|
|||
|
||||
After that, install the face_recognition python module. There's an excellent step by step guide on how to do this on [its github page](https://github.com/ageitgey/face_recognition#installation).
|
||||
|
||||
In the root of your cloned repo is a file called `config_template.py`. Duplicate this file and call it `config.py`. The `device_id` variable in this file is important, make sure it is the IR camera and not your normal webcam.
|
||||
In the root of your cloned repo is a file called `config.ini`. The `device_id` variable in this file is important, make sure it is the IR camera and not your normal webcam.
|
||||
|
||||
Now it's time to let Howdy learn your face. The learn.py script will make 3 models of your face and store them as an encoded set in the `models` folder. To run the script, open a terminal, navigate to this repository and run:
|
||||
|
||||
|
@ -22,7 +22,7 @@ python3 learn.py
|
|||
|
||||
The script should guide you through the process.
|
||||
|
||||
Finally we need to tell PAM that there's a new module installed. Open `/etc/pam.d/sudo` as root (`sudo nano /etc/pam.d/sudo`) and add the following line to the top of the file:
|
||||
Finally we need to tell PAM that there's a new module installed. Open `/etc/pam.d/common-auth` as root (`sudo nano /etc/pam.d/common-auth`) and add the following line to the top of the file:
|
||||
|
||||
```
|
||||
auth sufficient pam_python.so /path/to/pam.py
|
||||
|
|
16
compair.py
16
compair.py
|
@ -7,9 +7,11 @@ import cv2
|
|||
import sys
|
||||
import os
|
||||
import json
|
||||
import configparser
|
||||
|
||||
# Import config
|
||||
import config
|
||||
# Read config from disk
|
||||
config = configparser.ConfigParser()
|
||||
config.read(os.path.dirname(__file__) + "/config.ini")
|
||||
|
||||
def stop(status):
|
||||
"""Stop the execution and close video stream"""
|
||||
|
@ -34,14 +36,14 @@ tries = 0
|
|||
try:
|
||||
encodings = json.load(open(os.path.dirname(__file__) + "/models/" + user + ".dat"))
|
||||
except FileNotFoundError:
|
||||
stop(10)
|
||||
sys.exit(10)
|
||||
|
||||
# Verify that we have a valid model file
|
||||
if len(encodings) < 3:
|
||||
stop(1)
|
||||
sys.exit(1)
|
||||
|
||||
# Start video capture on the IR camera
|
||||
video_capture = cv2.VideoCapture(config.device_id)
|
||||
video_capture = cv2.VideoCapture(int(config.get("video", "device_id")))
|
||||
|
||||
while True:
|
||||
# Grab a single frame of video
|
||||
|
@ -57,11 +59,11 @@ while True:
|
|||
|
||||
# Check if any match is certain enough to be the user we're looking for
|
||||
for match in matches:
|
||||
if match < config.certainty and match > 0:
|
||||
if match < int(config.get("video", "certainty")) and match > 0:
|
||||
stop(0)
|
||||
|
||||
# Stop if we've exceded the maximum retry count
|
||||
if tries > config.frame_count:
|
||||
if tries > int(config.get("video", "frame_count")):
|
||||
stop(11)
|
||||
|
||||
tries += 1
|
||||
|
|
19
config.ini
Normal file
19
config.ini
Normal file
|
@ -0,0 +1,19 @@
|
|||
[core]
|
||||
# Do not print anything when a face vericication succeeds
|
||||
no_confirmation = false
|
||||
|
||||
# When a user without a known face model tries to use this script, don't
|
||||
# show an error but fail silently
|
||||
supress_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 recomended
|
||||
certainty = 3
|
||||
|
||||
# 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
|
||||
device_id = 1
|
|
@ -1,10 +0,0 @@
|
|||
# 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 recomended
|
||||
certainty = 3
|
||||
|
||||
# The number of frames to capture and to process before timing out
|
||||
frame_count = 80
|
||||
|
||||
# The /dev/videoX id to capture frames from
|
||||
# On my laptop, video0 is the normal camera and video1 is the IR version
|
||||
device_id = 1
|
21
pam.py
21
pam.py
|
@ -5,6 +5,13 @@ import subprocess
|
|||
import sys
|
||||
import os
|
||||
|
||||
# pam-python is running python 2, so we use the old module here
|
||||
import ConfigParser
|
||||
|
||||
# Read config from disk
|
||||
config = ConfigParser.ConfigParser()
|
||||
config.read(os.path.dirname(__file__) + "/config.ini")
|
||||
|
||||
def doAuth(pamh):
|
||||
"""Start authentication in a seperate process"""
|
||||
|
||||
|
@ -13,19 +20,21 @@ def doAuth(pamh):
|
|||
|
||||
# Status 10 means we couldn't find any face models
|
||||
if status == 10:
|
||||
print("No face model is known for this user, skiping")
|
||||
return pamh.PAM_SYSTEM_ERR
|
||||
if config.get("core", "supress_unknown") != "true":
|
||||
pamh.conversation(pamh.Message(pamh.PAM_ERROR_MSG, "No face model known"))
|
||||
return pamh.PAM_USER_UNKNOWN
|
||||
# Status 11 means we exceded the maximum retry count
|
||||
if status == 11:
|
||||
print("Timeout reached, could not find a known face")
|
||||
return pamh.PAM_SYSTEM_ERR
|
||||
pamh.conversation(pamh.Message(pamh.PAM_ERROR_MSG, "Face detection timeout reached"))
|
||||
return pamh.PAM_AUTH_ERR
|
||||
# Status 0 is a successful exit
|
||||
if status == 0:
|
||||
print("Identified face as " + os.environ.get("USER"))
|
||||
if config.get("core", "no_confirmation") != "true":
|
||||
pamh.conversation(pamh.Message(pamh.PAM_TEXT_INFO, "Identified face as " + pamh.get_user()))
|
||||
return pamh.PAM_SUCCESS
|
||||
|
||||
# Otherwise, we can't discribe what happend but it wasn't successful
|
||||
print("Unknown error: " + str(status))
|
||||
pamh.conversation(pamh.Message(pamh.PAM_ERROR_MSG, "Unknown error: " + str(status)))
|
||||
return pamh.PAM_SYSTEM_ERR
|
||||
|
||||
def pam_sm_authenticate(pamh, flags, args):
|
||||
|
|
Loading…
Reference in a new issue