def recognize_faces(self, image): # First, detect faces in the image face_boxes = self._detect_faces(image) # Crop and search for each face in the active registry rec_result = [] for face_box in face_boxes: box = face_box['box'] face_crop = image[box[1]:box[3], box[0]:box[2], :] bin_face_crop = opencv_image_to_binary_image(face_crop) try: resp = self._aws_client.search_faces_by_image( CollectionId=self._active_face_registry, Image={'Bytes': bin_face_crop}, MaxFaces=1, FaceMatchThreshold=self._matching_threshold) if len(resp['FaceMatches']) >= 1: match = resp['FaceMatches'][0] rec_result.append({ 'face_id': match['Face']['FaceId'], 'face_name': match['Face']['ExternalImageId'], 'recognition_score': match['Similarity'], 'box': box, 'detection_score': face_box['detection_score'] }) else: rec_result.append({ 'face_id': None, 'face_name': 'Unknown', 'recognition_score': None, 'box': box, 'detection_score': face_box['detection_score'] }) except Exception as e: logger.warning( 'Some error occured when searching for the face. ' 'Skipping this face. {}'.format(e)) rec_result.append({ 'face_id': None, 'face_name': 'Unknown', 'recognition_score': None, 'box': box, 'detection_score': face_box['detection_score'] }) return rec_result
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 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 _detect_faces(self, image): binary_image = opencv_image_to_binary_image(image) face_boxes = [] try: resp = self._aws_client.detect_faces( Image={'Bytes': binary_image}, Attributes=self._detection_attributes) for face_detail in resp['FaceDetails']: if face_detail['Confidence'] >= self._detection_threshold: face_box = AwsFaceRecognizer._decode_aws_bounding_box( face_detail['BoundingBox'], image.shape[1], image.shape[0]) score = face_detail['Confidence'] face_boxes.append({ 'detection_score': score, 'box': face_box }) except Exception as e: logger.warning('Error occured when detecting faces. {}'.format(e)) return face_boxes
def deregister_face(self, registry_name, face_id): try: resp = self._aws_client.delete_faces(CollectionId=registry_name, FaceIds=[face_id]) assert len(resp['DeletedFaces']) == 1 deleted_face_id = resp['DeletedFaces'][0] deleted_face_name = None logger.warning('Deleted face: {}'.format(deleted_face_id)) if registry_name == self._active_face_registry: idx = self._registry_face_ids.index(face_id) deleted_face_name = self._registry_face_names[idx] del self._registry_face_ids[idx] del self._registry_face_names[idx] del self._registry_faces[idx] return deleted_face_id, deleted_face_name except Exception as e: logger.warning('Error occured. Could not de-register face.') logger.warning(e) return None, None