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_)
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
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
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)
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
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
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
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)
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
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
def crop_face(self, img: Array3D, box: BoundingBoxDTO) -> Array3D: return face_align.norm_crop(img, landmark=box._np_landmarks, image_size=self.IMAGE_SIZE)
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], :]
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