Code cleanup

This commit is contained in:
boltgolt 2019-01-02 23:36:09 +01:00
parent e38422c8a0
commit 2917e8ada4
No known key found for this signature in database
GPG key ID: BECEC9937E1AAE26
4 changed files with 81 additions and 70 deletions

75
debian/postinst vendored
View file

@ -38,6 +38,7 @@ def handleStatus(status):
sys.exit(1)
# Create shorthand for subprocess creation
sc = subprocess.call
# We're not in fresh configuration mode so don't continue the setup
@ -98,79 +99,88 @@ handleStatus(sc(["pip3", "install", "--no-cache-dir", "--upgrade", "pip"]))
log("Downloading and unpacking data files")
# Run the bash script to download and unpack the .dat files needed
handleStatus(subprocess.call(["./install.sh"], shell=True, cwd="/lib/security/howdy/dlib-data"))
log('Downloading dlib')
log("Downloading dlib")
dlib_archive = '/tmp/v19.16.tar.gz'
loader = which('curl')
dlib_archive = "/tmp/v19.16.tar.gz"
loader = which("curl")
LOADER_CMD = None
# If curl is installed, use that as the downloader
if loader:
LOADER_CMD = [loader, '--retry', '5', '--location', '--output']
LOADER_CMD = [loader, "--retry", "5", "--location", "--output"]
# Otherwise, fall back on wget
else:
loader = which('wget')
LOADER_CMD = [loader, '--tries', '5', '--output-document']
cmd = LOADER_CMD + [dlib_archive, 'https://github.com/davisking/dlib/archive/v19.16.tar.gz']
loader = which("wget")
LOADER_CMD = [loader, "--tries", "5", "--output-document"]
# Assemble and execute the download command
cmd = LOADER_CMD + [dlib_archive, "https://github.com/davisking/dlib/archive/v19.16.tar.gz"]
handleStatus(sc(cmd))
# The folder containing the dlib source
DLIB_DIR = None
# A regex of all files to ignore while unpacking the archive
excludes = re.compile(
'davisking-dlib-\w+/(dlib/(http_client|java|matlab|test/)|'
'(docs|examples|python_examples)|'
'tools/(archive|convert_dlib_nets_to_caffe|htmlify|imglab|python/test|visual_studio_natvis))'
"davisking-dlib-\w+/(dlib/(http_client|java|matlab|test/)|"
"(docs|examples|python_examples)|"
"tools/(archive|convert_dlib_nets_to_caffe|htmlify|imglab|python/test|visual_studio_natvis))"
)
# Open the archive
with tarfile.open(dlib_archive) as tf:
for item in tf:
# tarball contains directory davisking-dlib-<commit id>, so peek into archive for the name
# Set the destenation dir if unset
if not DLIB_DIR:
DLIB_DIR = "/tmp/" + item.name
# extract only files sufficient for building
if not excludes.match(item.name):
tf.extract(item, '/tmp')
tf.extract(item, "/tmp")
# Delete the downloaded archive
os.unlink(dlib_archive)
log("Building dlib")
# Start the build
cmd = ["sudo", "python3", "setup.py", "install"]
cuda_used = False
flags = ""
flags = ''
with open('/proc/cpuinfo') as info:
# Get the CPU details
with open("/proc/cpuinfo") as info:
for line in info:
if 'flags' in line:
if "flags" in line:
flags = line
break
if 'avx' in flags:
# Use the most efficient instruction set the CPU supports
if "avx" in flags:
cmd += ["--yes", "USE_AVX_INSTRUCTIONS"]
elif 'sse4' in flags:
elif "sse4" in flags:
cmd += ["--yes", "USE_SSE4_INSTRUCTIONS"]
elif 'sse3' in flags:
elif "sse3" in flags:
cmd += ["--yes", "USE_SSE3_INSTRUCTIONS"]
elif 'sse2' in flags:
elif "sse2" in flags:
cmd += ["--yes", "USE_SSE2_INSTRUCTIONS"]
# Compile and link dlib
try:
sp = subprocess.Popen(cmd, cwd=DLIB_DIR, stdout=subprocess.PIPE)
except subprocess.CalledProcessError:
print("Error while building dlib")
raise
# Go through each line from stdout
while sp.poll() is None:
line = sp.stdout.readline().decode("utf-8")
if 'DLIB WILL USE CUDA' in line:
if "DLIB WILL USE CUDA" in line:
cuda_used = True
print(line, end='')
print(line, end="")
log("Cleaning up dlib")
@ -188,20 +198,19 @@ log("Configuring howdy")
# Manually change the camera id to the one picked
for line in fileinput.input(["/lib/security/howdy/config.ini"], inplace=1):
print(
line
.replace("device_path = none", "device_path = " + picked)
.replace("use_cnn = false", "use_cnn = " + str(cuda_used).lower()),
end=""
)
line = line.replace("device_path = none", "device_path = " + picked)
line = line.replace("use_cnn = false", "use_cnn = " + str(cuda_used).lower())
print(line, end="")
print("Camera ID saved")
# Secure the howdy folder
handleStatus(sc(["chmod 744 -R /lib/security/howdy/"], shell=True))
# Allow anyone to execute the python CLI
os.chmod('/lib/security/howdy', 0o755)
os.chmod('/lib/security/howdy/cli.py', 0o755)
os.chmod("/lib/security/howdy", 0o755)
os.chmod("/lib/security/howdy/cli.py", 0o755)
handleStatus(sc(["chmod 755 -R /lib/security/howdy/cli"], shell=True))
print("Permissions set")

3
debian/preinst vendored
View file

@ -9,6 +9,7 @@ def col(id):
if id == 3: return "\033[31m"
return "\033[0m"
import subprocess
import time
import sys
@ -24,7 +25,7 @@ if "upgrade" in sys.argv:
# Let the user know so he knows where to look on a failed install
print("Backup of Howdy config file created in /tmp/howdy_config_backup_v" + sys.argv[2] + ".ini")
except e:
except subprocess.CalledProcessError:
print("Could not make an backup of old Howdy config file")
# Don't continue setup when we're just upgrading

View file

@ -11,7 +11,7 @@ import builtins
# Try to get the original username (not "root") from shell
try:
user = os.getlogin()
except:
except Exception:
user = os.environ.get("SUDO_USER")
# If that fails, try to get the direct user

View file

@ -6,7 +6,7 @@ import time
# Start timing
timings = {
'st': time.time()
"st": time.time()
}
# Import required modules
@ -21,23 +21,21 @@ import _thread as thread
def init_detector(lock):
"""Start face detector, encoder and predictor in a new thread"""
global face_detector, pose_predictor, face_encoder
# 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'
)
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'
)
# Start the others regardless
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")
face_encoder = dlib.face_recognition_model_v1(
PATH + '/dlib-data/dlib_face_recognition_resnet_model_v1.dat'
)
# Note the time it took to initialize detectors
timings['ll'] = time.time() - timings['ll']
timings["ll"] = time.time() - timings["ll"]
lock.release()
@ -52,7 +50,7 @@ if len(sys.argv) < 2:
sys.exit(12)
# Get the absolute path to the current directory
PATH = os.path.abspath(__file__ + '/..')
PATH = os.path.abspath(__file__ + "/..")
# The username of the user being authenticated
user = sys.argv[1]
@ -86,25 +84,26 @@ if len(models) < 1:
config = configparser.ConfigParser()
config.read(PATH + "/config.ini")
# CNN usage flag
use_cnn = config.getboolean('core', 'use_cnn', fallback=False)
# Get all config values needed
use_cnn = config.getboolean("core", "use_cnn", fallback=False)
timeout = config.getint("video", "timout", fallback=5)
dark_threshold = config.getfloat("video", "dark_threshold", fallback=50.0)
video_certainty = config.getfloat("video", "certainty", fallback=3.5) / 10
end_report = config.getboolean("debug", "end_report", fallback=False)
# Save the time needed to start the script
timings['in'] = time.time() - timings['st']
timings["in"] = time.time() - timings["st"]
# Import face recognition, takes some time
timings['ll'] = time.time()
timings["ll"] = time.time()
# Start threading and wait for init to finish
lock = thread.allocate_lock()
lock.acquire()
thread.start_new_thread(init_detector, (lock, ))
# Start video capture on the IR camera
timings['ic'] = time.time()
timings["ic"] = time.time()
# Check if the user explicitly set ffmpeg as recorder
if config.get("video", "recording_plugin") == "ffmpeg":
@ -120,7 +119,8 @@ else:
# Force MJPEG decoding if true
if config.getboolean("video", "force_mjpeg", fallback=False):
# Set a magic number, will enable MJPEG but is badly documented
video_capture.set(cv2.CAP_PROP_FOURCC, 1196444237) # 1196444237 is 'GPJM' in ASCII
# 1196444237 is "GPJM" in ASCII
video_capture.set(cv2.CAP_PROP_FOURCC, 1196444237)
# Set the frame width and height if requested
fw = config.getint("video", "frame_width", fallback=-1)
@ -135,14 +135,13 @@ if fh != -1:
video_capture.grab()
# Note the time it took to open the camera
timings['ic'] = time.time() - timings['ic']
timings["ic"] = time.time() - timings["ic"]
# wait for thread to finish
lock.acquire()
lock.release()
del lock
# Fetch the max frame height
max_height = config.getfloat("video", "max_height", fallback=0.0)
# Get the height of the image
@ -158,14 +157,14 @@ end_report = config.getboolean("debug", "end_report")
# Start the read loop
frames = 0
timings['fr'] = time.time()
timings["fr"] = time.time()
while True:
# Increment the frame count every loop
frames += 1
# Stop if we've exceded the time limit
if time.time() - timings['fr'] > timeout:
if time.time() - timings["fr"] > timeout:
stop(11)
# Grab a single frame of video
@ -190,17 +189,18 @@ while True:
gsframe = cv2.resize(gsframe, None, fx=scaling_factor, fy=scaling_factor, interpolation=cv2.INTER_AREA)
# Get all faces from that frame as encodings
face_locations = face_detector(gsframe, 1) # upsample 1 time
# Upsamples 1 time
face_locations = face_detector(gsframe, 1)
# Loop through each face
for fl in face_locations:
if use_cnn:
fl = fl.rect
# Fetch the faces in the image
face_landmark = pose_predictor(frame, fl)
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))
# Match this found face against a known face
matches = np.linalg.norm(encodings - face_encoding, axis=1)
@ -210,8 +210,8 @@ while True:
# Check if a match that's confident enough
if 0 < match < video_certainty:
timings['tt'] = time.time() - timings['st']
timings['fr'] = time.time() - timings['fr']
timings["tt"] = time.time() - timings["st"]
timings["fr"] = time.time() - timings["fr"]
# If set to true in the config, print debug text
if end_report:
@ -219,13 +219,14 @@ while True:
"""Helper function to print a timing from the list"""
print(" %s: %dms" % (label, round(timings[k] * 1000)))
# Print a nice timing report
print("Time spent")
print_timing("Starting up", 'in')
print(" Open cam + load libs: %dms" % (round(max(timings['ll'], timings['ic']) * 1000, )))
print_timing(" Opening the camera", 'ic')
print_timing(" Importing recognition libs", 'll')
print_timing("Searching for known face", 'fr')
print_timing("Total time", 'tt')
print_timing("Starting up", "in")
print(" Open cam + load libs: %dms" % (round(max(timings["ll"], timings["ic"]) * 1000, )))
print_timing(" Opening the camera", "ic")
print_timing(" Importing recognition libs", "ll")
print_timing("Searching for known face", "fr")
print_timing("Total time", "tt")
print("\nResolution")
width = video_capture.get(cv2.CAP_PROP_FRAME_WIDTH) or 1
@ -235,7 +236,7 @@ while True:
print(" Used: %dx%d" % (scale_height, scale_width))
# Show the total number of frames and calculate the FPS by deviding it by the total scan time
print("\nFrames searched: %d (%.2f fps)" % (frames, frames / timings['fr']))
print("\nFrames searched: %d (%.2f fps)" % (frames, frames / timings["fr"]))
print("Dark frames ignored: %d " % (dark_tries, ))
print("Certainty of winning frame: %.3f" % (match * 10, ))