Code cleanup
This commit is contained in:
parent
e38422c8a0
commit
2917e8ada4
4 changed files with 81 additions and 70 deletions
75
debian/postinst
vendored
75
debian/postinst
vendored
|
|
@ -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
3
debian/preinst
vendored
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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, ))
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue