def find_faces(self, img: Array3D, det_prob_threshold: float = None) -> List[BoundingBoxDTO]: if det_prob_threshold is None: det_prob_threshold = self.det_prob_threshold assert 0 <= det_prob_threshold <= 1 scaler = ImgScaler(self.IMG_LENGTH_LIMIT) img = scaler.downscale_img(img) results = self._detection_model.get(img, det_thresh=det_prob_threshold) boxes = [] for result in results: downscaled_box_array = result.bbox.astype(np.int).flatten() downscaled_box = BoundingBoxDTO(x_min=downscaled_box_array[0], y_min=downscaled_box_array[1], x_max=downscaled_box_array[2], y_max=downscaled_box_array[3], probability=result.det_score, np_landmarks=result.landmark) box = downscaled_box.scaled(scaler.upscale_coefficient) if box.probability <= det_prob_threshold: logger.debug( f'Box Filtered out because below threshold ({det_prob_threshold}: {box})' ) continue logger.debug(f"Found: {box}") boxes.append(box) return boxes
def find_faces(self, img: Array3D, det_prob_threshold: float = None) -> List[BoundingBoxDTO]: if det_prob_threshold is None: det_prob_threshold = self.det_prob_threshold assert 0 <= det_prob_threshold <= 1 scaler = ImgScaler(self.IMG_LENGTH_LIMIT) img = scaler.downscale_img(img) fdn = self._face_detection_net detect_face_result = fdn.detect_faces(img) img_size = np.asarray(img.shape)[0:2] bounding_boxes = [] for face in detect_face_result: x, y, w, h = face['box'] box = BoundingBoxDTO( x_min=int(np.maximum(x - (self.left_margin * w), 0)), y_min=int(np.maximum(y - (self.top_margin * h), 0)), x_max=int(np.minimum(x + w + (self.right_margin * w), img_size[1])), y_max=int(np.minimum(y + h + (self.bottom_margin * h), img_size[0])), np_landmarks=np.array([list(value) for value in face['keypoints'].values()]), probability=face['confidence'] ) logger.debug(f"Found: {box}") bounding_boxes.append(box) filtered_bounding_boxes = [] for box in bounding_boxes: box = box.scaled(scaler.upscale_coefficient) if box.probability <= det_prob_threshold: logger.debug(f'Box filtered out because below threshold ({det_prob_threshold}): {box}') continue filtered_bounding_boxes.append(box) return filtered_bounding_boxes
def test__given_not_downscaled_image__when_upscaling_box__then_returns_same_box( ): img = np.zeros((20, 20, 3)) scaler = ImgScaler(img_length_limit=100) scaler.downscale_img(img) output_box = BoundingBoxDTO(10, 10, 20, 20, 1).scaled(scaler.upscale_coefficient) assert output_box == BoundingBoxDTO(10, 10, 20, 20, 1)
def test__given_5face_img__when_scanned__then_returns_5_correct_bounding_boxes_sorted_by_probability(scanner_cls): correct_boxes = [BoundingBoxDTO(544, 222, 661, 361, 1), BoundingBoxDTO(421, 236, 530, 369, 1), BoundingBoxDTO(161, 36, 266, 160, 1), BoundingBoxDTO(342, 160, 437, 268, 1), BoundingBoxDTO(243, 174, 352, 309, 1)] scanner: FaceScanner = scanner_cls() img = read_img(IMG_DIR / '000_5.jpg') faces = scanner.scan(img) for face in faces: assert face.box.similar_to_any(correct_boxes, tolerance=20) assert is_sorted([face.box.probability for face in faces])
def from_request(cls, result): return FaceDTO( box=BoundingBoxDTO(**result['box']), plugins_dto=[EmbeddingDTO(embedding=result['embedding'])], execution_time=result['execution_time'], face_img=None, img=None)
def scan(self, img: Array3D, det_prob_threshold: float = None) -> List[FaceDTO]: return [ FaceDTO(box=BoundingBoxDTO(0, 0, 0, 0, 0), plugins_dto=[EmbeddingDTO(embedding=np.random.rand(1))], img=img, face_img=img) ]
def scan(self, img: Array3D, det_prob_threshold: float = None) -> List[ScannedFace]: return [ ScannedFace(box=BoundingBoxDTO(0, 0, 0, 0, 0), embedding=np.random.rand(1), img=img, face_img=img) ]
def from_request(cls, result): box_result = result['box'] return ScannedFace(box=BoundingBoxDTO( x_min=box_result['x_min'], x_max=box_result['x_max'], y_min=box_result['y_min'], y_max=box_result['y_max'], probability=box_result['probability']), embedding=result['embedding'], img=None)
def find_faces(self, img: Array3D, det_prob_threshold: float = None) -> List[BoundingBoxDTO]: if det_prob_threshold is None: det_prob_threshold = self.det_prob_threshold assert 0 <= det_prob_threshold <= 1 scaler = ImgScaler(self.IMG_LENGTH_LIMIT) img = scaler.downscale_img(img) fdn = self._face_detection_nets detect_face_result = detect_face.detect_face( img, self.FACE_MIN_SIZE, fdn.pnet, fdn.rnet, fdn.onet, [self.det_threshold_a, self.det_threshold_b, self.det_threshold_c], self.SCALE_FACTOR) img_size = np.asarray(img.shape)[0:2] bounding_boxes = [] detect_face_result = list( zip(detect_face_result[0], detect_face_result[1].transpose())) for result_item, landmarks in detect_face_result: result_item = np.squeeze(result_item) margin = self.BOX_MARGIN / 2 box = BoundingBoxDTO( x_min=int(np.maximum(result_item[0] - margin, 0)), y_min=int(np.maximum(result_item[1] - margin, 0)), x_max=int(np.minimum(result_item[2] + margin, img_size[1])), y_max=int(np.minimum(result_item[3] + margin, img_size[0])), np_landmarks=landmarks.reshape(2, 5).transpose(), probability=result_item[4]) logger.debug(f"Found: {box}") bounding_boxes.append(box) filtered_bounding_boxes = [] for box in bounding_boxes: box = box.scaled(scaler.upscale_coefficient) if box.probability <= det_prob_threshold: logger.debug( f'Box filtered out because below threshold ({det_prob_threshold}): {box}' ) continue filtered_bounding_boxes.append(box) return filtered_bounding_boxes
def find_faces(self, img: Array3D, det_prob_threshold: float = None) -> List[BoundingBoxDTO]: return [BoundingBoxDTO(0, 0, 0, 0, 0)]
def dto(self): return BoundingBoxDTO(x_min=self.x_min, x_max=self.x_max, y_min=self.y_min, y_max=self.y_max, probability=self.probability)