def upload_photo(): logger.info("Processing request for upload-photo") status = config.HTTP_STATUS_OK try: file_list = list(request.files.keys()) num_files = len(file_list) logger.info(file_list) if num_files == 0: raise Exception( "Needs 1 image file but received {} files".format(num_files)) elif len(file_list) > 1: err_msg = "More than 2 files uploaded. Got {} files".format(num_files) raise Exception(err_msg) # Get POST parameters img = cv2.imdecode(np.fromstring(request.files[file_list[0]].read(), np.uint8), cv2.IMREAD_COLOR) # img = image_utils.read_b64(image_text) cropped_face = FM.get_face_from_image(img) base64_image = image_utils.image_to_b64(cropped_face) image_id = sql_utils.add_photo(base64_image) result={"image_id": image_id, "image_text":base64_image} except Exception as ex: logger.exception("Something went wrong") result = {"error" : str(ex)} status = config.HTTP_STATUS_ERROR resp = make_response(json.dumps(result), status ) resp.headers['Content-Type'] = 'application/json' return resp
def get_all_visitor_photos(): ''' Get photos of all visitors whose status is 0 ''' logger.info("Trying to fetch all visitor images") cnx = get_connection() try: cursor = cnx.cursor() query = ''' select v.id, i.image_data from visitor v, images i where v.status = 0 and v.uploaded_photo = i.image_id; ''' cursor.execute(query) res = cursor.fetchall() resp = [] for row in res: resp.append(row) cursor.close() cnx.close() except Exception as ex: logger.exception(str(ex)) raise Exception("Some thing went wrong") return resp
def __init__(self): self.altchars = "()".encode("utf-8") self.private_key_file = os.path.join(config.DATA_DIR, "private_key.pem") self.public_key_file = os.path.join(config.DATA_DIR, "public_key.pem") self.load_keys() logger.info("Encryption Model initialized")
def upload_photo_b64(): logger.info("Processing request for upload-photo-b64") status = config.HTTP_STATUS_OK try: if(request.headers['Content-Type'] != 'application/json'): return make_response('{"error":"unsupported content type"}', config.HTTP_STATUS_ERROR) # Get POST parameters input_json = request.json image_text = input_json["image"] img = image_utils.read_b64(image_text) cropped_face = FM.get_face_from_image(img) base64_image = image_utils.image_to_b64(cropped_face) image_id = sql_utils.add_photo(base64_image) result={"image_id": image_id, "image_text":base64_image} except Exception as ex: logger.exception("Something went wrong") result = {"error" : str(ex)} status = config.HTTP_STATUS_ERROR resp = make_response(json.dumps(result), status ) resp.headers['Content-Type'] = 'application/json' return resp
def approve_request(): ''' Show welcome message ! ''' # message = {"images" : sql_utils.get_photos(id)} # resp = make_response(json.dumps(message), config.HTTP_STATUS_OK) # resp.headers['Content-Type'] = 'application/json' # return resp logger.info("Processing request for approve request") status = config.HTTP_STATUS_OK result = {"success": "request approved"} try: code = request.args.get('code') visitor_id = int(EM.decrypt(code)) sql_utils.approve_request(visitor_id) except Exception as ex: logger.exception("Something went wrong") result = {"error": str(ex)} status = config.HTTP_STATUS_ERROR resp = make_response(json.dumps(result), status) resp.headers['Content-Type'] = 'application/json' return resp
def create_face_registry(self, registry_name): registry_path = self._get_face_registry_path(registry_name) if os.path.exists(registry_path): logger.info('Face registry already present. Not creating again') else: self._face_registries.append(registry_name) open(registry_path, 'w').close() return registry_name
def main(): ''' The main method ''' logger.info("Starting server on host : %s , port : %s !", config.HOST, config.PORT) start_http_server()
def set_active_face_registry(self, registry_name): if registry_name not in self._face_registries: raise ValueError( 'Face registry not found {}'.format(registry_name)) # Nothing to do logger.info('Setting active face registry to {}'.format(registry_name)) if self._active_face_registry == registry_name: return # TODO: Load the face registry self._active_face_registry = registry_name return self._active_face_registry
def _save_active_face_registry(self): registry_path = self._get_face_registry_path( self._active_face_registry) with open(registry_path, 'wb') as f: pickle.dump( { 'face_ids': self._registry_face_ids, 'face_names': self._registry_face_names, 'face_images': self._registry_faces, 'face_encodings': self._registry_face_encodings }, f) logger.info('Saved active face registry')
def create_face_registry(self, registry_name): if registry_name in self._face_registries: logger.info('Face registry already present. Not creating again') return registry_name try: resp = self._aws_client.create_collection( CollectionId=registry_name) logger.debug('Collection ARN: ' + resp['CollectionArn']) logger.debug('Status code: ' + str(resp['StatusCode'])) logger.info('Created face registry {}'.format(registry_name)) self._face_registries.append(registry_name) return registry_name except Exception as e: logger.fatal(e) return None
def __init__(self): logger.info('Creating edge face recognizer.') self._registry_faces = [] self._registry_face_names = [] self._registry_face_ids = [] self._registry_face_encodings = [] self._image_scale = 1.0 self._num_upsamples = 2 self._face_detector_type = 'cnn' # hog or 'cnn' self._matching_thr = 0.1 if not os.path.exists(FACE_REGISTRY_PATH): logger.info( 'Creating face registry at {}'.format(FACE_REGISTRY_PATH)) os.makedirs(FACE_REGISTRY_PATH) self._face_registries = self.list_face_registries() self._active_face_registry = None
def find_visitor_by_face(): ''' Find a visitor by face ''' logger.info("Processing request for find-visitor-by-face endpoint") status = config.HTTP_STATUS_OK try: message = do_post(request) except Exception as ex: logger.exception("Something went wrong !") message = {"error": str(ex)} status = config.HTTP_STATUS_ERROR resp = make_response(json.dumps(message), status) resp.headers['Content-Type'] = 'application/json' return resp
def delete_face_registry(self, registry_name): if registry_name not in self._face_registries: logger.warning( 'Looks like there is no such registry to delete.'.format( registry_name)) raise ValueError('No such face registry {}'.format(registry_name)) else: registry_path = self._get_face_registry_path(registry_name) os.remove(registry_path) if registry_name == self._active_face_registry: self._registry_face_names = [] self._registry_faces = [] self._registry_face_ids = [] self._registry_face_encodings = [] self._active_face_registry = None logger.info('Removed face registry {}'.format(registry_name)) return registry_name
def _load_face_registry(self, registry_name): reg_path = self._get_face_registry_path(registry_name) if os.path.exists(reg_path): with open(reg_path, 'rb') as f: try: data = pickle.load(f) self._registry_face_encodings = data['face_encodings'] self._registry_faces = data['face_images'] self._registry_face_names = data['face_names'] self._registry_face_ids = data['face_ids'] self._active_face_registry = registry_name logger.info( 'Loaded face registry {}. Set it as active face ' 'registry'.format(registry_name)) except Exception as e: logger.warning( 'Falied to load the face registry {}'.format(e))
def face_similarity_endpoint(): ''' Check similaity of faces in two images ''' logger.info("Processing request for face similarity endpoint") status = config.HTTP_STATUS_OK try: message = do_post(request) except Exception as ex: logger.exception("Something went wrong !") message = {"error": str(ex)} status = config.HTTP_STATUS_ERROR resp = make_response(json.dumps(message), status) resp.headers['Content-Type'] = 'application/json' return resp
def register_face(self, registry_name, image, name): if registry_name not in self._face_registries: raise ValueError('No such face registry {}'.format(registry_name)) if isinstance(image, str): image = face_recognition.load_image_file(image) face_boxes = face_recognition.face_locations( image, number_of_times_to_upsample=self._num_upsamples, model='cnn') if len(face_boxes) == 0: logger.warning('No faces found in the image') return None elif len(face_boxes) == 1: target_face_box = face_boxes[0] logger.info( 'Found one face in the image {}'.format(target_face_box)) else: target_face_box = EdgeFaceRecognizer._get_largest_face(face_boxes) logger.info( 'Found multiple faces in the image. Taking the largest one {}' ''.format(target_face_box)) face_crop = image[target_face_box[0]:target_face_box[2], target_face_box[3]:target_face_box[1], :] encoding = face_recognition.face_encodings( image, known_face_locations=[target_face_box]) new_face_id = self._get_new_face_id() if registry_name != self._active_face_registry: active_reg = self._active_face_registry self._load_face_registry(registry_name) assert registry_name == self._active_face_registry self._registry_faces.append(face_crop) self._registry_face_names.append(name) assert len(encoding) == 1 self._registry_face_encodings.append(encoding[0]) self._registry_face_ids.append(new_face_id) self._save_active_face_registry() # Restore active registry if registry_name != self._active_face_registry: self._load_face_registry(active_reg) return new_face_id
def delete_face_registry(self, registry_name): try: if registry_name not in self._face_registries: logger.warning( 'Looks like there is no such registry to delete.' 'Still trying with AWS'.format(registry_name)) resp = self._aws_client.delete_collection( CollectionId=registry_name) if registry_name in self._face_registries: self._face_registries.remove(registry_name) status_code = resp['StatusCode'] except ClientError as e: if e.response['Error']['Code'] == 'ResourceNotFoundException': logger.warning('Registry {} not found'.format(registry_name)) else: logger.error('Error occured: {}'.format( e.response['Error']['Message'])) status_code = e.response['ResponseMetadata']['HTTPStatusCode'] logger.info('Delete face registry status: {}'.format(status_code))
def get_face_from_image(self, img): ''' Find , crop and resize the face in the given image. Raises exception if no or more than 1 face found in the image ''' faces = [] for model in self.face_cascade_models: faces.extend(list(model.detectMultiScale(img))) logger.info("# of faces found is %d", len(faces)) face = image_utils.merge_faces(faces) x, y, w, h = face cropped_face = img[y:y + h, x:x + w] cropped_face = cv2.cvtColor(cropped_face, cv2.COLOR_BGR2RGB) cropped_face = cv2.resize(cropped_face, (224, 224)) return cropped_face
def get_connection(): logger.info("Trying to connect to MySQL database") cnx = None try: uid = os.environ.get(config.SQL_SERVER_USER_ID) pwd = os.environ.get(config.SQL_SERVER_USER_PWD) # print(uid, pwd) cnx = mysql.connector.connect(host=config.SQL_SERVER_IP, port=config.SQL_SERVER_PORT, user=uid, password=pwd, database=config.DB_NAME) except Exception: logger.exception("SQL Connection failed") exit(1) return cnx
def approve_request(visitor_id): ''' Set visitor status to approved ''' logger.info("Trying to approve visitor request") cnx = get_connection() try: cursor = cnx.cursor() query = '''update vms.visitor set status = 0 where id = %s ''' cursor.execute(query, (visitor_id, )) cursor.close() cnx.close() except Exception as ex: logger.exception(str(ex)) raise Exception("Could not approve this request") return "sucess"
def find(img): face = FM.get_face_from_image(img) face_vector = FM.vectorize(face.reshape((1, 224, 224, 3))) all_visitors = sql_utils.get_all_visitor_photos() logger.info("fetched %d visitor photos", len(all_visitors)) visitor_ids = [v[0] for v in all_visitors] visitor_faces = np.vstack([ image_utils.read_b64(v[1]).reshape((1, 224, 224, 3)) for v in all_visitors ]) logger.info(str(visitor_faces.shape)) visitor_vectors = FM.vectorize(visitor_faces) c = cosine_similarity(face_vector, visitor_vectors) c = c.reshape((c.shape[-1], )) max_similarity = np.max(c) logger.info("max simmilarity : {:.6f}".format(float(max_similarity))) if max_similarity >= 0.60: return visitor_ids[int(np.argmax(c))] raise Exception("No Match found")
def generate_code(): logger.info("Processing request for gerete code") status = config.HTTP_STATUS_OK try: if (request.headers['Content-Type'] != 'application/json'): return make_response('{"error":"unsupported content type"}', config.HTTP_STATUS_ERROR) # Get POST parameters input_json = request.json plain_text = input_json["plain_text"] cipher_text = EM.encrypt(plain_text) result = {"cipher_text": cipher_text} except Exception as ex: logger.exception("Something went wrong") result = {"error": str(ex)} status = config.HTTP_STATUS_ERROR resp = make_response(json.dumps(result), status) resp.headers['Content-Type'] = 'application/json' return resp
def get_photos(id=0): logger.info("fetching image with id %s", id) cnx = get_connection() try: cursor = cnx.cursor() cursor.execute( "SELECT image_id,image_data FROM images where image_id=%s", (int(id), )) res = cursor.fetchall() resp = [] for row in res: resp.append(row) cursor.close() cnx.close() except Exception as ex: logger.exception(str(ex)) raise Exception("Some thing went wrong") return resp
def do_post(request): ''' Process the uploaded files and compute their similarity ''' # step 1 : check if there is a file attachment logger.info(request.files) file_list = list(request.files.keys()) num_files = len(file_list) if num_files < 2: raise Exception( "Needs 2 image files but received {} files".format(num_files)) elif len(file_list) > 2: err_msg = "More than 2 files uploaded. Got {} files".format(num_files) raise Exception(err_msg) n = datetime.now() dir_name = "{}-{:02d}-{:02d}_{:02d}-{:02d}-{:02d}".format( n.year, n.month, n.day, n.hour, n.minute, n.second) full_dir_name = os.path.join(config.DATA_DIR, "requests", dir_name) if not os.path.exists(full_dir_name): os.makedirs(full_dir_name) file_path1 = check_save_file(request, file_list[0], full_dir_name) file_path2 = check_save_file(request, file_list[1], full_dir_name) img1 = image_utils.read_from_file(file_path1) face1 = FM.get_face_from_image(img1) img2 = image_utils.read_from_file(file_path2) face2 = FM.get_face_from_image(img2) score = FM.predict(face1, face2) score = float(score) logger.info("Similarity of %s and %s is %f", file_path1, file_path2, score) return {"similarity": score}
def load_keys(self): # check if both the key files exists if os.path.exists(self.private_key_file) and os.path.exists( self.public_key_file): logger.info("Loading keys from file") with open(self.private_key_file, "rb") as key_file: self.private_key = serialization.load_pem_private_key( key_file.read(), password=None, backend=default_backend()) with open(self.public_key_file, "rb") as key_file: self.public_key = serialization.load_pem_public_key( key_file.read(), backend=default_backend()) logger.info("Keys loaded from disk") else: logger.warn("key files does not exist. Creating them") self.private_key = rsa.generate_private_key( public_exponent=65537, key_size=config.KEY_SIZE, backend=default_backend()) self.public_key = self.private_key.public_key() logger.info("Keys generated. Now saving to disk") with open(self.private_key_file, 'wb') as f: pem = self.private_key.private_bytes( encoding=serialization.Encoding.PEM, format=serialization.PrivateFormat.PKCS8, encryption_algorithm=serialization.NoEncryption()) f.write(pem) logger.info("Private key saved at : %s", self.private_key_file) with open(self.public_key_file, 'wb') as f: pem = self.public_key.public_bytes( encoding=serialization.Encoding.PEM, format=serialization.PublicFormat.SubjectPublicKeyInfo) f.write(pem) logger.info("Public key saved at %s", self.public_key_file)
def __init__(self): ''' Initialize ''' logger.info("Initializing model") vggface = VGGFace(model='resnet50') out = vggface.get_layer("flatten_1").output self.model = Model(vggface.input, out) logger.info("vggface model initialized") self.face_cascade_models = [] for fname in config.FACE_CASCADE_MODELS: cv2_model_file = os.path.join(config.DATA_DIR, fname) if not os.path.exists(cv2_model_file): raise Exception("CV2 model file %s does not exist", cv2_model_file) self.face_cascade_models.append( cv2.CascadeClassifier(cv2_model_file)) logger.info("OpenCV cascade models initialized. # of models : %d", len(self.face_cascade_models))
def check_save_file(request, fname, dir_name): # check if the file in request is not empty file_obj = request.files[fname] filename = secure_filename(file_obj.filename) if filename == '': raise Exception("No or empty file") content_type = file_obj.content_type mime_type, _ = content_type.split("/") logger.info("Content_type of uploaded file is : %s", str(content_type)) if mime_type != "image": raise Exception("Unknown Mime Type {}".format(mime_type)) # Save the uploaded file logger.info("Uploaded File Name : %s", filename) file_path = os.path.join(dir_name, filename) logger.info("Saving to : %s", file_path) file_obj.save(file_path) return file_path
def __init__(self): FaceRecognizer.__init__(self) logger.info('Creating AWS Rekognition client.') self._aws_client = boto3.client('rekognition') self._face_registries = self._get_aws_collections() self._active_face_registry = None # Holds current registry details self._registry_faces = [] self._registry_face_names = [] self._registry_face_ids = [] self._detection_attributes = ['DEFAULT'] self._detection_threshold = 80.0 self._matching_threshold = 70.0 # Enabling this will get more facial attributes such as age, gender. # self._detection_attributes = ['DEFAULT', 'ALL'] logger.info('Created face recognizer.') logger.info('Existing face registries {}'.format( self._face_registries))
def register_face(self, registry_name, image, name): if registry_name not in self._face_registries: raise ValueError('No such face registry {}'.format(registry_name)) if isinstance(image, str): image = cv2.imread(image) binary_image = opencv_image_to_binary_image(image) resp = self._aws_client.index_faces(CollectionId=registry_name, Image={'Bytes': binary_image}, ExternalImageId=name, MaxFaces=1, QualityFilter="AUTO", DetectionAttributes=['ALL']) logger.info('Faces registered:') for face_record in resp['FaceRecords']: logger.info('Face ID: ' + face_record['Face']['FaceId']) logger.info('Location: {}'.format( face_record['Face']['BoundingBox'])) logger.info('Face name: ' + face_record['Face']['ExternalImageId']) if registry_name == self._active_face_registry: box = AwsFaceRecognizer._decode_aws_bounding_box( face_record['Face']['BoundingBox'], image.shape[1], image.shape[0]) crop = image[box[1]:box[3], box[0]:box[2], :] self._registry_face_ids.append(face_record['Face']['FaceId']) self._registry_face_names.append( face_record['Face']['ExternalImageId']) self._registry_faces.append(crop) logger.info('Faces not registered:') for unindexed_face in resp['UnindexedFaces']: logger.info('Location: {}'.format( unindexed_face['FaceDetail']['BoundingBox'])) logger.info('Reasons:') for reason in unindexed_face['Reasons']: logger.info(' ' + reason)