def process_src_img(self): src_face = self.detector.face_detection(self.src_img) if isinstance(src_face, int): # raise Exception("No face detected in src image!") return False src_face_rect = self.bbox_to_rect(src_face) self.src_points = face_points_detection(self.src_img, src_face_rect) # shrink the size of src image, to speed up. Although it is not obvious. # src_points_face = self.src_img.copy() # for (point_index, point) in enumerate(self.src_points): # cv2.circle(src_points_face, # (point[0], point[1]), 2, (0, 0, 255), -1) logging.info('''Select the Face and then press SPACE or ENTER button! Cancel the selection process by pressing c button!''') # while True: # initBB = cv2.selectROI("src_roi", src_points_face, # fromCenter=False, showCrosshair=False) # if initBB != (0, 0, 0, 0): # break # cv2.destroyWindow("src_roi") # (x, y, w, h) = initBB # (x, y, w, h)=(90 ,266, 372 ,402) # print(x,y,h,w) # self.src_points -= (x, y) # self.src_img = self.src_img[y:y + h, x:x + w] # print(self.src_points) src_mask = mask_from_points(self.src_img.shape[:2], self.src_points) self.src_only_face = apply_mask(self.src_img, src_mask) return True
def face_swap_2d(self, dst_img, dst_face_rect: dlib.rectangle): success = 1 failed = 0 dst_points = face_points_detection(dst_img, dst_face_rect) if not check_points(dst_img, dst_points): logging.error("part of Face") return (failed, dst_img) dst_mask = mask_from_points(dst_img.shape[:2], dst_points, erode_flag=1) r = cv2.boundingRect(dst_points) (x, y, w, h) = r if y + h > dst_img.shape[0] or x + w > dst_img.shape[1]: logging.error("part of landmarks out of face") return (failed, dst_img) dst_roi = dst_img[y:y + h, x:x + w] dst_mask = dst_mask[y:y + h, x:x + w] dst_points -= (x, y) dst_only_face = apply_mask(dst_roi, dst_mask) warped_src_face = warp_image_2d( self.src_only_face, transformation_from_points(dst_points, self.src_points), (h, w, 3)) new_src_face = correct_colours(dst_only_face, warped_src_face, dst_points) center = (int(x + w / 2), int(y + h / 2)) output = cv2.seamlessClone(new_src_face, dst_img, dst_mask, center, cv2.NORMAL_CLONE) return (success, output)
def slow_face_swap(self, dst_img, dst_face_rect: dlib.rectangle): dst_points = face_points_detection(dst_img, dst_face_rect) # 4ms w, h = dst_img.shape[:2] warped_dst_img = warp_image_3d(dst_img, dst_points[:48], self.src_points[:48], self.src_only_face.shape[:2]) # 140ms self.src_only_face = correct_colours(warped_dst_img, self.src_only_face, self.src_points) warped_src_img = warp_image_3d(self.src_only_face, self.src_points[:48], dst_points[:48], (w, h)) dst_mask = mask_from_points((w, h), dst_points) r = cv2.boundingRect(dst_mask) center = ((r[0] + int(r[2] / 2), r[1] + int(r[3] / 2))) output = cv2.seamlessClone(warped_src_img, dst_img, dst_mask, center, cv2.NORMAL_CLONE) return output
def draw_landmarks(self, dst_img, dst_face_bbox): dst_points = face_points_detection(dst_img, dst_face_bbox) for (point_index, point) in enumerate(dst_points): cv2.circle(dst_img, (point[0], point[1]), 2, (0, 0, 255), -1) cv2.putText(dst_img, str(point_index), (point[0], point[1]), cv2.FONT_HERSHEY_SIMPLEX, 0.35, (0, 0, 255), 1)