mti840-projet/cloud/cloud/compute.py

75 lines
2.2 KiB
Python

import queue
import threading
import logging
import base64
from urllib.parse import urlparse
import pickle
import json
import cv2
import numpy as np
import requests
from cloud.models import (
User,
DBSession
)
compute_queue = queue.Queue()
def find_identity(face, db, recognizer, labels, threshold=.6):
preds = recognizer.predict_proba([face])[0]
idx = np.argmax(preds)
proba = preds[idx]
if proba > threshold:
uid = labels.classes_[idx]
user = db.query(User).filter_by(uid=uid).one()
return (user, proba)
def load_recognizer(filename):
with open(filename, 'rb') as infile:
model = pickle.load(infile)
recognizer = model['recognizer']
labels = model['labels']
return (recognizer, labels)
def process_face(recognizer, labels):
logging.info('Processing thread started')
session = DBSession()
while True:
uid, b64faces = compute_queue.get()
bytefaces = map(base64.b64decode, b64faces)
faces = (np.frombuffer(bf, dtype='float32') for bf in bytefaces)
identities = set(filter(None, (find_identity(
face, session, recognizer, labels) for face in faces)))
users = [id[0] for id in identities]
logging.info(
'Found %d distinct indentities from faces from %s',
len(identities), uid)
logging.info(repr(identities))
for user, proba in identities:
matches = [device for device in user.devices if device.uid == uid]
if matches:
device = matches[0]
try:
logging.info('Sending opening door action')
payload = json.dumps({'state': 'open'})
requests.put(device.callback, data=payload)
except Exception as e:
logging.warning('Error while sending action: %s', str(e))
break
def start_processing(settings, nb_thread=4):
logging.info('Starting processing threads...')
recognizer, labels = load_recognizer(settings.get('iot.model'))
for i in range(nb_thread):
thread = threading.Thread(
target=process_face, args=(recognizer, labels), daemon=True)
thread.start()