def get_input_all(self, face_img):
     bbox, pts5 = self.detector.detect(face_img, threshold=0.5)
     if bbox.shape[0] == 0:
         return None, None, None, None
     if bbox is None:
         return None, None, None, None
     output = []
     faces_ = []
     key_points_ = []
     bboxes_ = []
     for face, point in zip(bbox, pts5):
         bbox = face[0:4].astype(np.int)
         #return(bbox)
         # print (point.shape,point,bbox.shape,bbox)
         #point=point.reshape((2,5)).T
         to_add_face = face_img[bbox[1]:bbox[3], bbox[0]:bbox[2]]
         faces_.append(to_add_face)
         key_points_.append((point.astype(np.int), face[4]))
         bboxes_.append(bbox)
         # cv2.imshow("cropped",to_add_face)
         nimg = face_align.norm_crop(face_img, point)
         # cv2.imshow("alligned_cropped",nimg)
         # cv2.waitKey(0)
         # cv2.destroyAllWindows()
         #nimg = cv2.cvtColor(nimg, cv2.COLOR_BGR2RGB)
         aligned = np.transpose(nimg, (2, 0, 1))
         output.append(aligned)
     return np.array(output), faces_, np.array(key_points_), np.array(
         bboxes_)
예제 #2
0
def prepare_images(root_dir: Path,
                   output_dir: Path,
                   detector: Detector,
                   choose_face: Callable[[Scores, Bboxes, int, int], int],
                   small_face: int = -1) -> None:
    logging.info(
        f'Starting preparation: input dir {root_dir} output dir {output_dir}')
    img_paths = list(img_generator(root_dir))
    for img_path, (scores, bboxes, landmarks) in zip(
            img_paths, tqdm(detector(img_paths), total=len(img_paths))):
        new_path = output_dir / img_path.relative_to(root_dir)
        ensure_path(new_path.parent)
        img = cv2.imread(str(img_path))
        height, width = img.shape[:2]
        if len(landmarks) < 1:
            logging.warning(f'smth wrong with {img_path}')
            continue
        face_idx = choose_face(scores, bboxes, width, height)
        if small_face > 0:
            bbox = bboxes[face_idx]
            if bbox[2] - bbox[0] < small_face or bbox[3] - bbox[1] < small_face:
                logging.warning(f'small face in image {img_path}')
                continue
        warped_img = norm_crop(img, landmarks[face_idx])
        cv2.imwrite(str(new_path), warped_img)
 def get_input(self, face_img):
     bbox, pts5 = self.detector.detect(face_img, threshold=0.8)
     if bbox.shape[0] == 0:
         return None
     bbox = bbox[0, 0:4]
     pts5 = pts5[0, :]
     nimg = face_align.norm_crop(face_img, pts5)
     return nimg
예제 #4
0
 def get_input(self, face_img):
     bboxs, pts5 = self.detector.detect(face_img, threshold=0.8)
     # print(bboxs)
     if bboxs.shape[0] == 0:
         return None, None
     bboxs = bboxs[:, 0:4]
     pts5 = pts5[:, :]
     nimg = [face_align.norm_crop(face_img, pt5) for pt5 in pts5]
     return nimg, bboxs
예제 #5
0
    def compute_embeddings(self, image, bounding_boxes, **kwargs):
        assert 'kpss' in kwargs, (
            "kpss is not in kwargs, probably using wrong detector model")
        kpss = kwargs.get('kpss')

        embeddings = []
        for bb, kps in zip(bounding_boxes, kpss):
            aimg = face_align.norm_crop(image, kps)
            embedding = self._embedder.get_feat(aimg).flatten()
            embeddings.append(embedding / np.linalg.norm(embedding))
        return np.array(embeddings)
예제 #6
0
    async def get(self, img, extract_embedding: bool = True, extract_ga: bool = True,
                  return_face_data: bool = True, max_size: List[int] = None, threshold: float = 0.6):

        ts = time.time()
        t0 = time.time()

        # If detector has input_shape attribute, use it instead of provided value
        try:
            max_size = self.det_model.retina.input_shape[2:][::-1]
        except:
            pass

        img = ImageData(img, max_size=max_size)
        img.resize_image(mode='pad')
        t1 = time.time()
        logging.debug(f'Preparing image took: {t1 - t0}')

        t0 = time.time()
        boxes, probs, landmarks, mask_probs = self.det_model.detect(img.transformed_image, threshold=threshold)
        t1 = time.time()
        logging.debug(f'Detection took: {t1 - t0}')
        faces = []
        await asyncio.sleep(0)
        if not isinstance(boxes, type(None)):
            t0 = time.time()
            for i in range(len(boxes)):
                # Translate points to original image size
                bbox = self.reproject_points(boxes[i], img.scale_factor)
                landmark = self.reproject_points(landmarks[i], img.scale_factor)
                det_score = probs[i]

                if not isinstance(mask_probs, type(None)):
                    mask_prob = mask_probs[i]
                else:
                    mask_prob = None

                # Crop faces from original image instead of resized to improve quality
                _crop = face_align.norm_crop(img.orig_image, landmark=landmark)
                face = Face(bbox=bbox, landmark=landmark, det_score=det_score,
                            num_det=i, scale=img.scale_factor, mask_prob=mask_prob, facedata=_crop)

                faces.append(face)

            t1 = time.time()
            logging.debug(f'Cropping {len(boxes)} faces took: {t1 - t0}')

            # Process detected faces
            faces = [e for e in self.process_faces(faces, extract_embedding=extract_embedding,
                                                   extract_ga=extract_ga, return_face_data=return_face_data)]

        tf = time.time()
        logging.debug(f'Full processing took: {tf - ts}')
        return faces
예제 #7
0
 def scan(self,
          img: Array3D,
          det_prob_threshold: float = None) -> List[ScannedFace]:
     scanned_faces = []
     for bounding_box in self.find_faces(img, det_prob_threshold):
         norm_cropped_img = face_align.norm_crop(
             img, landmark=bounding_box.landmark)
         embedding = self._calculation_model.get_embedding(
             norm_cropped_img).flatten()
         scanned_faces.append(
             ScannedFace(box=bounding_box, embedding=embedding, img=img))
     return scanned_faces
예제 #8
0
    def get(self, img, extract_embedding: bool = True, extract_ga: bool = True,
            return_face_data: bool = True, max_size: List[int] = None, threshold: float = 0.6):

        if max_size is None:
            max_size = self.max_size

        img = ImageData(img, max_size=max_size)
        img.resize_image(pad=True)

        boxes, probs, landmarks = self.det_model.detect(img.transformed_image, threshold=threshold)

        ret = []
        if not isinstance(boxes, type(None)):
            for i in range(len(boxes)):
                # Translate points to original image size
                bbox = self.reproject_points(boxes[i], img.scale_factor)
                landmark = self.reproject_points(landmarks[i], img.scale_factor)
                det_score = probs[i]
                # Crop faces from original image instead of resized to improve quality
                _crop = face_align.norm_crop(img.orig_image, landmark=landmark)
                facedata = None
                embedding = None
                embedding_norm = None
                normed_embedding = None
                gender = None
                age = None
                if return_face_data:
                    facedata = _crop
                if extract_embedding and self.rec_model:
                    embedding = self.rec_model.get_embedding(_crop).flatten()
                    embedding_norm = norm(embedding)
                    normed_embedding = embedding / embedding_norm

                if self.ga_model:
                    if extract_ga:
                        gender, age = self.ga_model.get(_crop)
                        gender = int(gender)

                face = Face(bbox=bbox, landmark=landmark, det_score=det_score, embedding=embedding, gender=gender,
                            age=age,
                            normed_embedding=normed_embedding, embedding_norm=embedding_norm, facedata=facedata,
                            num_det=i,
                            scale=img.scale_factor)

                ret.append(face)

        return ret
    def detect_and_align(self, face_img, img_detect_size):

        face_img = square_crop(face_img, img_detect_size)

        if self.detector_type == "mtcnn":
            ret = self.detector.detect_face(face_img)
            print("RET: ", ret)
            if ret is None:
                print("No image found")
                return None
            bbox, points = ret
            print("bbox: ", bbox, np.shape(bbox[:, 0])[0])
            print("points: ", points, np.shape(points[:, 0]))
            if bbox.shape[0] == 0:
                return None


            bbox = bbox[0, 0:4]
            pts5 = points[0, :].reshape((2, 5)).T
        else:
            bbox, pts5 = self.detector.detect(face_img, threshold=0.8)
            if bbox.shape[0] == 0:
                return None
            # print(bbox)
            idx_max_box = self.get_largest_face(bbox)
            bbox = bbox[idx_max_box, 0:4]


            # head_img = self.extend_and_crop_head(face_img, bbox, ratio_extend=0.4)
            # bbox, pts5 = self.detector.detect(head_img, threshold=0.8)
            # if bbox.shape[0] == 0:
            #     return None
            pts5 = pts5[idx_max_box, :]

        head_img = face_img
        nimg = face_align.norm_crop(head_img, pts5)

        img_raw = head_img.copy()
        for b in pts5:
                # landms
                cv2.circle(img_raw, (b[0], b[1]), 1, (0, 0, 255), 4)

            # save image

        name = "result.jpg"
        cv2.imwrite(name, img_raw)
        return nimg
예제 #10
0
def prepare_images(root_dir, output_dir):
    whitelist_dir = 'MID'
    detector = model_zoo.get_model('retinaface_r50_v1')
    detector.prepare(ctx_id=-1, nms=0.4)

    for family_path in tqdm(root_dir.iterdir()):
        for person_path in family_path.iterdir():
            if not person_path.is_dir() or not person_path.name.startswith(whitelist_dir):
                continue
            output_person = ensure_path(output_dir / person_path.relative_to(root_dir))
            for img_path in person_path.iterdir():
                img = cv2.imread(str(img_path))
                bbox, landmarks = detector.detect(img, threshold=0.5, scale=1.0)
                output_path = output_person / img_path.name
                if len(landmarks) < 1:
                    print(f'smth wrong with {img_path}')
                    continue
                warped_img = norm_crop(img, landmarks[0])
                cv2.imwrite(str(output_path), warped_img)
예제 #11
0
    async def get(self,
                  img,
                  extract_embedding: bool = True,
                  extract_ga: bool = True,
                  return_face_data: bool = True,
                  max_size: List[int] = None,
                  threshold: float = 0.6):

        ts = time.time()

        t0 = time.time()
        # If detector has input_shape attribute, use it instead of provided value
        try:
            max_size = self.det_model.retina.input_shape[2:][::-1]
        except:
            pass
        img = ImageData(img, max_size=max_size)
        img.resize_image(mode='pad')
        t1 = time.time()
        logging.debug(f'Preparing image took: {t1 - t0}')

        t0 = time.time()
        boxes, probs, landmarks = self.det_model.detect(img.transformed_image,
                                                        threshold=threshold)
        t1 = time.time()
        logging.debug(f'Detection took: {t1 - t0}')
        await asyncio.sleep(0)
        ret = []
        if not isinstance(boxes, type(None)):
            t0 = time.time()
            for i in range(len(boxes)):
                # Translate points to original image size
                bbox = self.reproject_points(boxes[i], img.scale_factor)
                landmark = self.reproject_points(landmarks[i],
                                                 img.scale_factor)
                det_score = probs[i]
                # Crop faces from original image instead of resized to improve quality
                _crop = face_align.norm_crop(img.orig_image, landmark=landmark)
                facedata = None
                embedding = None
                embedding_norm = None
                normed_embedding = None
                gender = None
                age = None
                if return_face_data:
                    facedata = _crop

                if extract_embedding and self.rec_model:
                    embedding = self.rec_model.get_embedding(_crop).flatten()
                    embedding_norm = norm(embedding)
                    normed_embedding = embedding / embedding_norm

                if self.ga_model:
                    if extract_ga:
                        gender, age = self.ga_model.get(_crop)
                        gender = int(gender)

                face = Face(bbox=bbox,
                            landmark=landmark,
                            det_score=det_score,
                            embedding=embedding,
                            gender=gender,
                            age=age,
                            normed_embedding=normed_embedding,
                            embedding_norm=embedding_norm,
                            facedata=facedata,
                            num_det=i,
                            scale=img.scale_factor)

                ret.append(face)
            t1 = time.time()
            logging.debug(f'Embedding {len(boxes)} faces took: {t1 - t0}')
            await asyncio.sleep(0)

        tf = time.time()
        logging.debug(f'Full processing took: {tf - ts}')
        return ret
예제 #12
0
    def get(self, img, extract_embedding: bool = True, extract_ga: bool = True,
            return_face_data: bool = True, max_size: List[int] = None, threshold: float = 0.6):

        ts = time.time()

        t0 = time.time()

        # If detector has input_shape attribute, use it instead of provided value
        try:
            max_size = self.det_model.retina.input_shape[2:][::-1]
        except:
            pass
        img = ImageData(img, max_size=max_size)
        img.resize_image(mode='pad')
        t1 = time.time()
        logging.debug(f'Preparing image took: {t1 - t0}')

        t0 = time.time()
        boxes, probs, landmarks, mask_probs = self.det_model.detect(img.transformed_image, threshold=threshold)
        t1 = time.time()
        logging.debug(f'Detection took: {t1 - t0}')
        ret = []
        if not isinstance(boxes, type(None)):
            t0 = time.time()
            for i in range(len(boxes)):
                # Translate points to original image size
                bbox = self.reproject_points(boxes[i], img.scale_factor)
                landmark = self.reproject_points(landmarks[i], img.scale_factor)
                det_score = probs[i]
                if not isinstance(mask_probs, type(None)):
                    mask_prob = mask_probs[i]
                else:
                    mask_prob = None

                # Crop faces from original image instead of resized to improve quality
                _crop = face_align.norm_crop(img.orig_image, landmark=landmark)
                # _crop = cv2.resize(_crop, (48, 48))
                # _crop = cv2.resize(_crop, (112, 112))
                embedding = self.rec_model.get_embedding(_crop)
                embedding_norm = norm(embedding)
                normed_embedding = embedding / embedding_norm
                # print(normed_embedding.shape)
                # print(_crop.shape)
                facedata = None
                gender = None
                age = None
                if return_face_data:
                    facedata = _crop


                # if self.ga_model:
                #     if extract_ga:
                #         gender, age = self.ga_model.get(_crop)
                #         gender = int(gender)


                face = Face(bbox=bbox, landmark=landmark, det_score=det_score, facedata=facedata, num_det=i, scale=img.scale_factor, mask_prob=mask_prob, normed_embedding=normed_embedding)
                ret.append(face)
            t1 = time.time()
            logging.debug(f'Cropping {len(boxes)} faces took: {t1 - t0}')

            # Embedding detected faces
            # if extract_embedding and self.rec_model:
            #     t0 = time.time()
            #     ret = [e for e in self.embed_faces(ret)]
            #     t1 = time.time()
            #     logging.debug(f'Embedding {len(boxes)} faces took: {t1 - t0}')

        tf = time.time()
        logging.debug(f'Full processing took: {tf - ts}')
        return ret
예제 #13
0
 def crop_face(self, img: Array3D, box: BoundingBoxDTO) -> Array3D:
     return face_align.norm_crop(img,
                                 landmark=box._np_landmarks,
                                 image_size=self.IMAGE_SIZE)
예제 #14
0
 def get_crop(self, box, landmark=None):
     b = [max(0, int(x)) for x in box]
     if landmark is not None:
         return face_align.norm_crop(self.data, landmark=landmark)
     else:
         return self.data[b[1]:b[3], b[0]:b[2], :]
예제 #15
0
    def detect_and_align(cls,
                         raw_input_image,
                         is_source_image=False,
                         threshold=0.70):
        face_detector, _ = cls.get_model()

        height, width, _ = raw_input_image.shape
        short_size = height if height < width else width
        scale = 1.0 if short_size < 480.0 else 480.0 / short_size

        bbox_list, pts5_list = face_detector.detect(raw_input_image,
                                                    threshold=threshold,
                                                    scale=scale)

        if bbox_list.shape[0] == 0:
            return None

        if is_source_image:
            max_face_index = cls.get_largest_face(bbox_list)
            bbox = bbox_list[max_face_index, :]
            pts5 = pts5_list[max_face_index, :]
            aligned_source_face = face_align.norm_crop(raw_input_image, pts5)

            face = Face(bbox=[
                float(bbox[0]),
                float(bbox[1]),
                float(bbox[2]),
                float(bbox[3])
            ],
                        aligned_face_img=aligned_source_face,
                        confidence=float(bbox[-1]),
                        key_points={
                            'eyeLeft': [float(pts5[0][0]),
                                        float(pts5[0][1])],
                            'eyeRight': [float(pts5[1][0]),
                                         float(pts5[1][1])],
                            'nose': [float(pts5[2][0]),
                                     float(pts5[2][1])],
                            'mouthLeft':
                            [float(pts5[3][0]),
                             float(pts5[3][1])],
                            'mouthRight':
                            [float(pts5[4][0]),
                             float(pts5[4][1])],
                        })

            return face
        else:
            face_list = list()
            for index in range(len(bbox_list)):
                bbox = bbox_list[index]
                pts5 = pts5_list[index]

                aligned_target_face = face_align.norm_crop(
                    raw_input_image, pts5)

                face = Face(bbox=[
                    float(bbox[0]),
                    float(bbox[1]),
                    float(bbox[2]),
                    float(bbox[3])
                ],
                            aligned_face_img=aligned_target_face,
                            confidence=float(bbox[-1]),
                            key_points={
                                'eyeLeft':
                                [float(pts5[0][0]),
                                 float(pts5[0][1])],
                                'eyeRight':
                                [float(pts5[1][0]),
                                 float(pts5[1][1])],
                                'nose': [float(pts5[2][0]),
                                         float(pts5[2][1])],
                                'mouthLeft':
                                [float(pts5[3][0]),
                                 float(pts5[3][1])],
                                'mouthRight':
                                [float(pts5[4][0]),
                                 float(pts5[4][1])],
                            })

                face_list.append(face)
            return face_list