def head_pose(frame): global prn try: pos = prn.process(frame) kpt = prn.get_landmarks(pos) vertices = prn.get_vertices(pos) camera_matrix, pose = estimate_pose(vertices) if pose[1] > config.SPEED_STEP: color = COLOR_UP elif pose[1] < -config.SPEED_STEP: color = COLOR_DOWN else: color = COLOR_STAY frame = plot_pose_box(frame, camera_matrix, kpt, color=color) except: pose = (0.0, 0.0, 0.0) return frame, pose
def main(args): if args.isShow or args.isTexture: import cv2 from utils.cv_plot import plot_kpt, plot_vertices, plot_pose_box # ---- init PRN os.environ['CUDA_VISIBLE_DEVICES'] = args.gpu # GPU number, -1 for CPU prn = PRN(is_dlib=args.isDlib) # ------------- load data image_folder = args.inputDir save_folder = args.outputDir if not os.path.exists(save_folder): os.mkdir(save_folder) types = ('*.jpg', '*.png') image_path_list = [] if os.path.isfile(image_folder): image_path_list.append(image_folder) for files in types: image_path_list.extend(glob(os.path.join(image_folder, files))) total_num = len(image_path_list) for i, image_path in enumerate(image_path_list): name = image_path.strip().split('/')[-1][:-4] # read image image = imread(image_path) [h, w, _] = image.shape # the core: regress position map if args.isDlib: max_size = max(image.shape[0], image.shape[1]) if max_size > 1000: image = rescale(image, 1000. / max_size) image = (image * 255).astype(np.uint8) pos, crop_image = prn.process(image) # use dlib to detect face else: if image.shape[1] == image.shape[2]: image = resize(image, (256, 256)) pos = prn.net_forward( image / 255.) # input image has been cropped to 256x256 crop_image = None else: box = np.array([0, image.shape[1] - 1, 0, image.shape[0] - 1 ]) # cropped with bounding box pos, crop_image = prn.process(image, box) image = image / 255. if pos is None: continue if args.is3d or args.isMat or args.isPose or args.isShow: # 3D vertices vertices = prn.get_vertices(pos) if args.isFront: save_vertices = frontalize(vertices) else: save_vertices = vertices.copy() save_vertices[:, 1] = h - 1 - save_vertices[:, 1] if args.isImage and crop_image is not None: imsave(os.path.join(save_folder, name + '_crop.jpg'), crop_image) imsave(os.path.join(save_folder, name + '_orig.jpg'), image) if args.is3d: # corresponding colors colors = prn.get_colors(image, vertices) if args.isTexture: texture = cv2.remap(image, pos[:, :, :2].astype(np.float32), None, interpolation=cv2.INTER_NEAREST, borderMode=cv2.BORDER_CONSTANT, borderValue=(0)) if args.isMask: vertices_vis = get_visibility(vertices, prn.triangles, h, w) uv_mask = get_uv_mask(vertices_vis, prn.triangles, prn.uv_coords, h, w, prn.resolution_op) texture = texture * uv_mask[:, :, np.newaxis] write_obj_with_texture( os.path.join(save_folder, name + '.obj'), save_vertices, colors, prn.triangles, texture, prn.uv_coords / prn.resolution_op ) #save 3d face with texture(can open with meshlab) else: write_obj(os.path.join(save_folder, name + '.obj'), save_vertices, colors, prn.triangles) #save 3d face(can open with meshlab) if args.isDepth: depth_image = get_depth_image(vertices, prn.triangles, h, w, True) depth = get_depth_image(vertices, prn.triangles, h, w) imsave(os.path.join(save_folder, name + '_depth.jpg'), depth_image) sio.savemat(os.path.join(save_folder, name + '_depth.mat'), {'depth': depth}) if args.isMat: sio.savemat(os.path.join(save_folder, name + '_mesh.mat'), { 'vertices': vertices, 'colors': colors, 'triangles': prn.triangles }) if args.isKpt or args.isShow: # get landmarks kpt = prn.get_landmarks(pos) np.savetxt(os.path.join(save_folder, name + '_kpt.txt'), kpt) if args.isPose or args.isShow: # estimate pose camera_matrix, pose = estimate_pose(vertices) np.savetxt(os.path.join(save_folder, name + '_pose.txt'), pose) np.savetxt(os.path.join(save_folder, name + '_camera_matrix.txt'), camera_matrix) np.savetxt(os.path.join(save_folder, name + '_pose.txt'), pose) if args.isShow: # ---------- Plot image_pose = plot_pose_box(image, camera_matrix, kpt) cv2.imshow('sparse alignment', plot_kpt(image, kpt)) cv2.imshow('dense alignment', plot_vertices(image, vertices)) cv2.imshow('pose', plot_pose_box(image, camera_matrix, kpt)) if crop_image is not None: cv2.imshow('crop', crop_image) cv2.waitKey(0)
if args.isMat: # sio.savemat(os.path.join(save_folder, name + '_mesh.mat'), {'vertices': vertices, 'colors': colors, 'triangles': prn.triangles}) pass if args.isKpt or args.isShow: # get landmarks kpt = prn.get_landmarks(pos) # np.savetxt(os.path.join(save_folder, name + '_kpt.txt'), kpt) if args.isPose or args.isShow: # estimate pose camera_matrix, pose = estimate_pose(vertices) # np.savetxt(os.path.join(save_folder, name + '_pose.txt'), pose) # np.savetxt(os.path.join(save_folder, name + '_camera_matrix.txt'), camera_matrix) # np.savetxt(os.path.join(save_folder, name + '_pose.txt'), pose) if args.isShow: # ---------- Plot image_pose = plot_pose_box(image, camera_matrix, kpt) cv2.imshow('sparse alignment', plot_kpt(image, kpt)) cv2.imshow('dense alignment', plot_vertices(image, vertices)) cv2.imshow('pose', plot_pose_box(image, camera_matrix, kpt)) #cv2.waitKey(0) frame_count += 1 if cv2.waitKey(1) & 0xFF == ord('q'): break print('\nAverage FPS: ', frame_count / (time.time() - start))
def main(args): # 1. load pre-tained model checkpoint_fp = 'models/phase1_wpdc_vdc.pth.tar' arch = 'mobilenet_1' checkpoint = torch.load( checkpoint_fp, map_location=lambda storage, loc: storage)['state_dict'] model = getattr(mobilenet_v1, arch)( num_classes=62) # 62 = 12(pose) + 40(shape) +10(expression) model_dict = model.state_dict() # because the model is trained by multiple gpus, prefix module should be removed for k in checkpoint.keys(): model_dict[k.replace('module.', '')] = checkpoint[k] model.load_state_dict(model_dict) if args.mode == 'gpu': cudnn.benchmark = True model = model.cuda() model.eval() # 2. load dlib model for face detection and landmark used for face cropping if args.dlib_landmark: dlib_landmark_model = 'models/shape_predictor_68_face_landmarks.dat' face_regressor = dlib.shape_predictor(dlib_landmark_model) if args.dlib_bbox: face_detector = dlib.get_frontal_face_detector() # 3. forward tri = sio.loadmat('visualize/tri.mat')['tri'] transform = transforms.Compose( [ToTensorGjz(), NormalizeGjz(mean=127.5, std=128)]) for img_fp in args.files: img_ori = cv2.imread(img_fp) if args.dlib_bbox: rects = face_detector(img_ori, 1) else: rects = [] if len(rects) == 0: rects = dlib.rectangles() rect_fp = img_fp + '.bbox' try: lines = open(rect_fp).read().strip().split('\n')[1:] except FileNotFoundError: print('Cannot load bbox file') continue for l in lines: l, r, t, b = [int(_) for _ in l.split(' ')[1:]] rect = dlib.rectangle(l, r, t, b) rects.append(rect) pts_res = [] Ps = [] # Camera matrix collection poses = [] # pose collection, [todo: validate it] vertices_lst = [] # store multiple face vertices ind = 0 suffix = get_suffix(img_fp) for rect in rects: # whether use dlib landmark to crop image, if not, use only face bbox to calc roi bbox for cropping if args.dlib_landmark: # - use landmark for cropping pts = face_regressor(img_ori, rect).parts() pts = np.array([[pt.x, pt.y] for pt in pts]).T roi_box = parse_roi_box_from_landmark(pts) else: # - use detected face bbox bbox = [rect.left(), rect.top(), rect.right(), rect.bottom()] roi_box = parse_roi_box_from_bbox(bbox) img = crop_img(img_ori, roi_box) # forward: one step img = cv2.resize(img, dsize=(STD_SIZE, STD_SIZE), interpolation=cv2.INTER_LINEAR) input = transform(img).unsqueeze(0) with torch.no_grad(): if args.mode == 'gpu': input = input.cuda() param = model(input) param = param.squeeze().cpu().numpy().flatten().astype( np.float32) # 68 pts pts68 = predict_68pts(param, roi_box) # two-step for more accurate bbox to crop face if args.bbox_init == 'two': roi_box = parse_roi_box_from_landmark(pts68) img_step2 = crop_img(img_ori, roi_box) img_step2 = cv2.resize(img_step2, dsize=(STD_SIZE, STD_SIZE), interpolation=cv2.INTER_LINEAR) input = transform(img_step2).unsqueeze(0) with torch.no_grad(): if args.mode == 'gpu': input = input.cuda() param = model(input) param = param.squeeze().cpu().numpy().flatten().astype( np.float32) pts68 = predict_68pts(param, roi_box) pts_res.append(pts68) P, pose = parse_pose(param) Ps.append(P) poses.append(pose) # dense face 3d vertices if args.dump_ply or args.dump_vertex or args.dump_depth or args.dump_pncc or args.dump_obj: vertices = predict_dense(param, roi_box) vertices_lst.append(vertices) if args.dump_ply: dump_to_ply( vertices, tri, '{}_{}.ply'.format(img_fp.replace(suffix, ''), ind)) if args.dump_vertex: dump_vertex( vertices, '{}_{}.mat'.format(img_fp.replace(suffix, ''), ind)) if args.dump_pts: wfp = '{}_{}.txt'.format(img_fp.replace(suffix, ''), ind) np.savetxt(wfp, pts68, fmt='%.3f') print('Save 68 3d landmarks to {}'.format(wfp)) if args.dump_roi_box: wfp = '{}_{}.roibox'.format(img_fp.replace(suffix, ''), ind) np.savetxt(wfp, roi_box, fmt='%.3f') print('Save roi box to {}'.format(wfp)) if args.dump_paf: wfp_paf = '{}_{}_paf.jpg'.format(img_fp.replace(suffix, ''), ind) wfp_crop = '{}_{}_crop.jpg'.format(img_fp.replace(suffix, ''), ind) paf_feature = gen_img_paf(img_crop=img, param=param, kernel_size=args.paf_size) cv2.imwrite(wfp_paf, paf_feature) cv2.imwrite(wfp_crop, img) print('Dump to {} and {}'.format(wfp_crop, wfp_paf)) if args.dump_obj: wfp = '{}_{}.obj'.format(img_fp.replace(suffix, ''), ind) colors = get_colors(img_ori, vertices) write_obj_with_colors(wfp, vertices, tri, colors) print('Dump obj with sampled texture to {}'.format(wfp)) ind += 1 if args.dump_pose: # P, pose = parse_pose(param) # Camera matrix (without scale), and pose (yaw, pitch, roll, to verify) img_pose = plot_pose_box(img_ori, Ps, pts_res) wfp = img_fp.replace(suffix, '_pose.jpg') cv2.imwrite(wfp, img_pose) print('Dump to {}'.format(wfp)) if args.dump_depth: wfp = img_fp.replace(suffix, '_depth.png') # depths_img = get_depths_image(img_ori, vertices_lst, tri-1) # python version depths_img = cget_depths_image(img_ori, vertices_lst, tri - 1) # cython version cv2.imwrite(wfp, depths_img) print('Dump to {}'.format(wfp)) if args.dump_pncc: wfp = img_fp.replace(suffix, '_pncc.png') pncc_feature = cpncc(img_ori, vertices_lst, tri - 1) # cython version cv2.imwrite( wfp, pncc_feature[:, :, ::-1]) # cv2.imwrite will swap RGB -> BGR print('Dump to {}'.format(wfp)) if args.dump_res: draw_landmarks(img_ori, pts_res, wfp=img_fp.replace(suffix, '_3DDFA.jpg'), show_flg=args.show_flg)
def drawPose(img, shape2D, Ps): pts_res = [] pts_res.append(shape2D) plot_pose_box(img, Ps, pts_res)
def main(args): if args.isShow: args.isOpencv = True from utils.cv_plot import plot_kpt, plot_vertices, plot_pose_box if args.isObj: from utils.write import write_obj if args.isPose: from utils.estimate_pose import estimate_pose # ---- init PRN os.environ['CUDA_VISIBLE_DEVICES'] = args.gpu # GPU number, -1 for CPU prn = PRN(is_dlib=args.isDlib, is_opencv=args.isOpencv) # ------------- load data image_folder = args.inputFolder save_folder = args.outputFolder if not os.path.exists(save_folder): os.mkdir(save_folder) types = ('*.jpg', '*.png') image_path_list = [] for files in types: image_path_list.extend(glob(os.path.join(image_folder, files))) total_num = len(image_path_list) for i, image_path in enumerate(image_path_list): name = image_path.strip().split('/')[-1][:-4] # read image image = imread(image_path) # the core: regress position map pos = prn.process(image) # use dlib to detect face if args.isObj or args.isShow: # 3D vertices vertices = prn.get_vertices(pos) # corresponding colors colors = prn.get_colors(image, vertices) write_obj(os.path.join(save_folder, name + '.obj'), vertices, colors, prn.triangles) #save 3d face(can open with meshlab) if args.isKpt or args.isShow: # get landmarks kpt = prn.get_landmarks(pos) np.savetxt(os.path.join(save_folder, name + '_kpt.txt'), kpt) if args.isPose or args.isShow: # estimate pose camera_matrix, pose = estimate_pose(vertices) np.savetxt(os.path.join(save_folder, name + '_pose.txt'), pose) if args.isShow: # ---------- Plot image_pose = plot_pose_box(image, camera_matrix, kpt) cv2.imshow('sparse alignment', plot_kpt(image, kpt)) cv2.imshow('dense alignment', plot_vertices(image, vertices)) cv2.imshow('pose', plot_pose_box(image, camera_matrix, kpt)) cv2.waitKey(0)
def main(args): if args.isShow or args.isTexture: import cv2 from utils.cv_plot import plot_kpt, plot_vertices, plot_pose_box # ---- transform transform_img = transforms.Compose([ transforms.ToTensor(), transforms.Normalize(FLAGS["normalize_mean"], FLAGS["normalize_std"]) ]) # ---- init PRN prn = PRN(args.model) # ------------- load data image_folder = args.inputDir save_folder = args.outputDir if not os.path.exists(save_folder): os.mkdir(save_folder) types = ('*.jpg', '*.png') image_path_list = [] for files in types: image_path_list.extend(glob(os.path.join(image_folder, files))) total_num = len(image_path_list) print("#" * 25) print("[PRNet Inference] {} picture were under processing~".format( total_num)) print("#" * 25) for i, image_path in enumerate(image_path_list): name = image_path.strip().split('/')[-1][:-4] # read image image = cv2.imread(image_path) [h, w, c] = image.shape # the core: regress position map image = cv2.resize(image, (256, 256)) image_t = transform_img(image) image_t = image_t.unsqueeze(0) pos = prn.net_forward( image_t) # input image has been cropped to 256x256 out = pos.cpu().detach().numpy() pos = np.squeeze(out) cropped_pos = pos * 255 pos = cropped_pos.transpose(1, 2, 0) if pos is None: continue if args.is3d or args.isMat or args.isPose or args.isShow: # 3D vertices vertices = prn.get_vertices(pos) if args.isFront: save_vertices = frontalize(vertices) else: save_vertices = vertices.copy() save_vertices[:, 1] = h - 1 - save_vertices[:, 1] if args.isImage: cv2.imwrite(os.path.join(save_folder, name + '.jpg'), image) if args.is3d: # corresponding colors colors = prn.get_colors(image, vertices) if args.isTexture: if args.texture_size != 256: pos_interpolated = cv2.resize( pos, (args.texture_size, args.texture_size), preserve_range=True) else: pos_interpolated = pos.copy() texture = cv2.remap(image, pos_interpolated[:, :, :2].astype( np.float32), None, interpolation=cv2.INTER_LINEAR, borderMode=cv2.BORDER_CONSTANT, borderValue=(0)) if args.isMask: vertices_vis = get_visibility(vertices, prn.triangles, h, w) uv_mask = get_uv_mask(vertices_vis, prn.triangles, prn.uv_coords, h, w, prn.resolution_op) uv_mask = cv2.resize( uv_mask, (args.texture_size, args.texture_size), preserve_range=True) texture = texture * uv_mask[:, :, np.newaxis] write_obj_with_texture( os.path.join(save_folder, name + '.obj'), save_vertices, prn.triangles, texture, prn.uv_coords / prn.resolution_op ) # save 3d face with texture(can open with meshlab) else: write_obj_with_colors( os.path.join(save_folder, name + '.obj'), save_vertices, prn.triangles, colors) # save 3d face(can open with meshlab) # if args.isDepth: # depth_image = get_depth_image(vertices, prn.triangles, h, w, True) # depth = get_depth_image(vertices, prn.triangles, h, w) # cv2.imwrite(os.path.join(save_folder, name + '_depth.jpg'), depth_image) # sio.savemat(os.path.join(save_folder, name + '_depth.mat'), {'depth': depth}) if args.isKpt or args.isShow: # get landmarks kpt = prn.get_landmarks(pos) np.savetxt(os.path.join(save_folder, name + '_kpt.txt'), kpt) if args.isPose or args.isShow: # estimate pose camera_matrix, pose = estimate_pose(vertices) np.savetxt(os.path.join(save_folder, name + '_pose.txt'), pose) np.savetxt(os.path.join(save_folder, name + '_camera_matrix.txt'), camera_matrix) np.savetxt(os.path.join(save_folder, name + '_pose.txt'), pose) if args.isShow: # ---------- Plot image_pose = plot_pose_box(image, camera_matrix, kpt) cv2.imshow('sparse alignment', plot_kpt(image, kpt)) cv2.imshow('dense alignment', plot_vertices(image, vertices)) cv2.imshow('pose', plot_pose_box(image, camera_matrix, kpt)) cv2.waitKey(0)
def main(args): if args.isShow or args.isTexture: import cv2 from utils.cv_plot import plot_kpt, plot_vertices, plot_pose_box # ---- init PRN os.environ['CUDA_VISIBLE_DEVICES'] = args.gpu # GPU number, -1 for CPU prn = PRN(is_dlib = args.isDlib) # ------------- load data image_folder = args.inputDir save_folder = args.outputDir if not os.path.exists(save_folder): os.mkdir(save_folder) # types = ('*.jpg', '*.png') # image_path_list= [] # for files in types: # image_path_list.extend(glob(os.path.join(image_folder, files))) # total_num = len(image_path_list) for dir, dirs, files in sorted(os.walk(image_folder)): for file in files: image_path = os.path.join(dir, file) dir = dir.replace("\\", "/") new_dir = dir.replace(image_folder, save_folder) if not os.path.isdir(new_dir): os.mkdir(new_dir) name = image_path.replace(image_folder, save_folder) print('data path:', name) # read image image = imread(image_path) [h, w, c] = image.shape if c>3: image = image[:,:,:3] # the core: regress position map if args.isDlib: max_size = max(image.shape[0], image.shape[1]) if max_size> 1000: image = rescale(image, 1000./max_size) image = (image*255).astype(np.uint8) pos = prn.process(image) # use dlib to detect face else: # if image.shape[0] == image.shape[1]: # image = resize(image, (256,256)) # pos = prn.net_forward(image/255.) # input image has been cropped to 256x256 # else: box = np.array([0, image.shape[1]-1, 0, image.shape[0]-1]) # cropped with bounding box pos = prn.process(image, box) image = image/255. if pos is None: continue if args.is3d or args.isMat or args.isPose or args.isShow: # 3D vertices vertices = prn.get_vertices(pos) if args.isFront: save_vertices = frontalize(vertices) else: save_vertices = vertices.copy() save_vertices[:,1] = h - 1 - save_vertices[:,1] if args.isImage: imsave(name, image) if args.is3d: # corresponding colors colors = prn.get_colors(image, vertices) if args.isTexture: if args.texture_size != 256: pos_interpolated = resize(pos, (args.texture_size, args.texture_size), preserve_range = True) else: pos_interpolated = pos.copy() texture = cv2.remap(image, pos_interpolated[:,:,:2].astype(np.float32), None, interpolation=cv2.INTER_LINEAR, borderMode=cv2.BORDER_CONSTANT,borderValue=(0)) if args.isMask: vertices_vis = get_visibility(vertices, prn.triangles, h, w) uv_mask = get_uv_mask(vertices_vis, prn.triangles, prn.uv_coords, h, w, prn.resolution_op) uv_mask = resize(uv_mask, (args.texture_size, args.texture_size), preserve_range = True) texture = texture*uv_mask[:,:,np.newaxis] write_obj_with_texture(name.replace('.jpg', '.obj'), save_vertices, prn.triangles, texture, prn.uv_coords/prn.resolution_op)#save 3d face with texture(can open with meshlab) else: write_obj_with_colors(name.replace('.jpg', '.obj'), save_vertices, prn.triangles, colors) #save 3d face(can open with meshlab) filepath = name.replace('.jpg', '.obj') filepath = filepath.replace("\\", "/") print('filepath:', filepath) new_dir = dir.replace(args.inputDir, args.renderDir) # print(new_dir + '/' + file) if not os.path.isdir(new_dir): os.mkdir(new_dir) color_image1, _ = render_scene(filepath, 4.0, 0.0, 3.0) color_image2, _ = render_scene(filepath, 4.0, np.pi / 18.0, 3.0) color_image3, _ = render_scene(filepath, 4.0, np.pi / 9.0, 3.0) if color_image1 is None or color_image2 is None: continue new_path = filepath.replace(args.outputDir, args.renderDir) # print('new_path:', new_path) save_image(new_path, '_40_', color_image1) save_image(new_path, '_50_', color_image2) save_image(new_path, '_60_', color_image3) os.remove(name.replace('.jpg', '.obj')) if args.isDepth: depth_image = get_depth_image(vertices, prn.triangles, h, w, True) depth = get_depth_image(vertices, prn.triangles, h, w) imsave(os.path.join(name.replace('.jpg', '_depth.jpg')), depth_image) sio.savemat(name.replace('.jpg', '_depth.mat'), {'depth': depth}) if args.isMat: sio.savemat(name.replace('.jpg', '_mesh.mat'), {'vertices': vertices, 'colors': colors, 'triangles': prn.triangles}) if args.isKpt or args.isShow: # get landmarks kpt = prn.get_landmarks(pos) np.savetxt(name.replace('.jpg', '_kpt.txt'), kpt) if args.isPose or args.isShow: # estimate pose camera_matrix, pose = estimate_pose(vertices) np.savetxt(name.replace('.jpg', '_pose.txt'), pose) np.savetxt(name.replace('.jpg', '_camera_matrix.txt'), camera_matrix) np.savetxt(name.replace('.jpg', '_pose.txt'), pose) if args.isShow: # ---------- Plot image_pose = plot_pose_box(image, camera_matrix, kpt) cv2.imshow('sparse alignment', plot_kpt(image, kpt)) cv2.imshow('dense alignment', plot_vertices(image, vertices)) cv2.imshow('pose', plot_pose_box(image, camera_matrix, kpt)) cv2.waitKey(0)
def main(args): if args.isShow or args.isTexture: import cv2 from utils.cv_plot import plot_kpt, plot_vertices, plot_pose_box # ---- init PRN os.environ['CUDA_VISIBLE_DEVICES'] = args.gpu # GPU number, -1 for CPU prn = PRN(is_dlib = args.isDlib) # ------------- load data image_folder = args.inputDir save_folder = args.outputDir if not os.path.exists(save_folder): os.mkdir(save_folder) types = ('*.jpg', '*.png') image_path_list= [] for files in types: image_path_list.extend(glob(os.path.join(image_folder, files))) total_num = len(image_path_list) for i, image_path in enumerate(image_path_list): name = image_path.strip().split('/')[-1][:-4] # read image image = imread(image_path) [h, w, _] = image.shape # the core: regress position map if args.isDlib: max_size = max(image.shape[0], image.shape[1]) if max_size> 1000: image = rescale(image, 1000./max_size) pos = prn.process(image) # use dlib to detect face else: if image.shape[1] == image.shape[2]: image = resize(image, (256,256)) pos = prn.net_forward(image/255.) # input image has been cropped to 256x256 else: box = np.array([0, image.shape[1]-1, 0, image.shape[0]-1]) # cropped with bounding box pos = prn.process(image, box) image = image/255. if pos is None: continue if args.is3d or args.isMat or args.isPose or args.isShow: # 3D vertices vertices = prn.get_vertices(pos) if args.isFront: save_vertices = frontalize(vertices) else: save_vertices = vertices if args.isImage: imsave(os.path.join(save_folder, name + '.jpg'), image) if args.is3d: # corresponding colors colors = prn.get_colors(image, vertices) if args.isTexture: texture = cv2.remap(image, pos[:,:,:2].astype(np.float32), None, interpolation=cv2.INTER_NEAREST, borderMode=cv2.BORDER_CONSTANT,borderValue=(0)) if args.isMask: vertices_vis = get_visibility(vertices, prn.triangles, h, w) uv_mask = get_uv_mask(vertices_vis, prn.triangles, prn.uv_coords, h, w, prn.resolution_op) texture = texture*uv_mask[:,:,np.newaxis] write_obj_with_texture(os.path.join(save_folder, name + '.obj'), save_vertices, colors, prn.triangles, texture, prn.uv_coords/prn.resolution_op)#save 3d face with texture(can open with meshlab) else: write_obj(os.path.join(save_folder, name + '.obj'), save_vertices, colors, prn.triangles) #save 3d face(can open with meshlab) if args.isDepth: depth_image = get_depth_image(vertices, prn.triangles, h, w) imsave(os.path.join(save_folder, name + '_depth.jpg'), depth_image) if args.isMat: sio.savemat(os.path.join(save_folder, name + '_mesh.mat'), {'vertices': save_vertices, 'colors': colors, 'triangles': prn.triangles}) if args.isKpt or args.isShow: # get landmarks kpt = prn.get_landmarks(pos) np.savetxt(os.path.join(save_folder, name + '_kpt.txt'), kpt) if args.isPose or args.isShow: # estimate pose camera_matrix, pose = estimate_pose(vertices) np.savetxt(os.path.join(save_folder, name + '_pose.txt'), pose) if args.isShow: # ---------- Plot image_pose = plot_pose_box(image, camera_matrix, kpt) cv2.imshow('sparse alignment', plot_kpt(image, kpt)) cv2.imshow('dense alignment', plot_vertices(image, vertices)) cv2.imshow('pose', plot_pose_box(image, camera_matrix, kpt)) cv2.waitKey(0)
def test_video(args): start_time = time.time() x = 1 # displays the frame rate every 1 second counter = 0 # 1. load pre-tained model # checkpoint_fp='models/phase1_wpdc_vdc_v2.pth.tar' # arch='mobilenet_1' checkpoint_fp = 'models/MobDenseNet.pth.tar' arch = 'mobdensenet_v1' checkpoint = torch.load( checkpoint_fp, map_location=lambda storage, loc: storage)['state_dict'] model = getattr(MobDenseNet, arch)( num_classes=62) # 62 = 12(pose) + 40(shape) +10(expression) model_dict = model.state_dict() # because the model is trained by multiple gpus, prefix module should be removed for k in checkpoint.keys(): model_dict[k.replace('module.', '')] = checkpoint[k] model.load_state_dict(model_dict) if args.mode == 'gpu': cudnn.benchmark = True model = model.cuda() model.eval() # 2. load dlib model for face detection and landmark used for face cropping if args.dlib_landmark: dlib_landmark_model = 'models/shape_predictor_68_face_landmarks.dat' face_regressor = dlib.shape_predictor(dlib_landmark_model) if args.dlib_bbox: face_detector = dlib.get_frontal_face_detector() # 3. forward tri = sio.loadmat('visualize/tri.mat')['tri'] - 1 tri_pts68 = sio.loadmat('visualize/pats68_tri.mat')['tri'] textureImg = cv2.imread(image_name) cameraImg = cap.read()[1] # textureCoords=df.getFaceTextureCoords(textureImg) # drawface=Drawing3DFace.Draw3DFace(cameraImg,textureImg,textureCoords,tri_pts68.T) transform = transforms.Compose( [ToTensorGjz(), NormalizeGjz(mean=127.5, std=128)]) while True: # get a frame img_ori = cap.read()[1] imgScale = 1 scaledImg = img_ori if max(img_ori.shape) > maxImgSizeForDetection: imgScale = maxImgSizeForDetection / float(max(img_ori.shape)) scaledImg = cv2.resize(img_ori, (int(img_ori.shape[1] * imgScale), int(img_ori.shape[0] * imgScale))) rects = face_detector(scaledImg, 1) Ps = [] # Camera matrix collection poses = [] # pose collection pts_res = [] # suffix=get_suffix(img_ori) for rect in rects: if args.dlib_landmark: faceRectangle = rectangle(int(rect.left() / imgScale), int(rect.top() / imgScale), int(rect.right() / imgScale), int(rect.bottom() / imgScale)) # - use landmark for cropping pts = face_regressor(img_ori, faceRectangle).parts() pts = np.array([[pt.x, pt.y] for pt in pts]).T roi_box = parse_roi_box_from_landmark(pts) else: bbox = [ int(rect.left() / imgScale), int(rect.top() / imgScale), int(rect.right() / imgScale), int(rect.bottom() / imgScale) ] roi_box = parse_roi_box_from_bbox(bbox) img = crop_img(img_ori, roi_box) # forward: one step img = cv2.resize(img, dsize=(STD_SIZE, STD_SIZE), interpolation=cv2.INTER_LINEAR) input = transform(img).unsqueeze(0) with torch.no_grad(): if args.mode == 'gpu': input = input.cuda() param = model(input) param = param.squeeze().cpu().numpy().flatten().astype(np.float32) # 68 pts pts68 = predict_68pts(param, roi_box) # df.triDelaunay(pts68) densePts = predict_dense(param, roi_box) P, pose = parse_pose(param) Ps.append(P) poses.append(pose) # two-step for more accurate bbox to crop face if args.bbox_init == 'two': roi_box = parse_roi_box_from_landmark(pts68) img_step2 = crop_img(img_ori, roi_box) img_step2 = cv2.resize(img_step2, dsize=(STD_SIZE, STD_SIZE), interpolation=cv2.INTER_LINEAR) input = transform(img_step2).unsqueeze(0) with torch.no_grad(): if args.mode == 'gpu': input = input.cuda() param = model(input) param = param.squeeze().cpu().numpy().flatten().astype( np.float32) pts68 = predict_68pts(param, roi_box) pts_res.append(pts68) pts = [] #draw landmark for indx in range(68): pos = (pts68[0, indx], pts68[1, indx]) pts.append(pos) cv2.circle(img_ori, pos, 3, color=(255, 255, 255), thickness=-1) ##draw pose box if args.dump_pose: img_ori = plot_pose_box(img_ori, Ps, pts_res) #draw face mesh if args.dump_2D_face_mesh: img_ori = df.drawMesh(img_ori, densePts.T, tri.T) if args.dump_3D_face_mesh: pass # img=drawface.render(pts68) cv2.imshow("faceDetector", img_ori) counter += 1 if (time.time() - start_time) > x: print("FPS: ", counter / (time.time() - start_time)) counter = 0 start_time = time.time() if cv2.waitKey(1) & 0xFF == ord('q'): break cap.release() cv2.destroyAllWindows()
def process_one_frame(frame): if frame is None: print("No frame, check your camera") img_ori = frame img_fp = "camera.png" # 随便给一个filename 反正之后用不到 rects = face_detector(img_ori, 1) pts_res = [] Ps = [] # Camera matrix collection poses = [] # pose collection, [todo: validate it] vertices_lst = [] # store multiple face vertices ind = 0 suffix = get_suffix(img_fp) for i in range(len(rects)): if i != 0: break # 这里只检测第一个脸 rect = rects[i] # whether use dlib landmark to crop image, if not, use only face bbox to calc roi bbox for cropping # - use landmark for cropping pts = face_regressor(img_ori, rect).parts() pts = np.array([[pt.x, pt.y] for pt in pts]).T roi_box = parse_roi_box_from_landmark(pts) img = crop_img(img_ori, roi_box) # forward: one step img = cv2.resize(img, dsize=(STD_SIZE, STD_SIZE), interpolation=cv2.INTER_LINEAR) input = transform(img).unsqueeze(0) with torch.no_grad(): if use_gpu: input = input.cuda() param = model(input) param = param.squeeze().cpu().numpy().flatten().astype( np.float32) # 68 pts pts68 = predict_68pts(param, roi_box) # two-step for more accurate bbox to crop face if use_two_step_bbox_init: roi_box = parse_roi_box_from_landmark(pts68) img_step2 = crop_img(img_ori, roi_box) img_step2 = cv2.resize(img_step2, dsize=(STD_SIZE, STD_SIZE), interpolation=cv2.INTER_LINEAR) input = transform(img_step2).unsqueeze(0) with torch.no_grad(): if use_gpu: input = input.cuda() param = model(input) param = param.squeeze().cpu().numpy().flatten().astype( np.float32) pts68 = predict_68pts(param, roi_box) pts_res.append(pts68) P, pose = parse_pose(param) Ps.append(P) poses.append(pose) # dense face 3d vertices vertices = predict_dense(param, roi_box) vertices_lst.append(vertices) if is_dump_to_ply: dump_to_ply( vertices, tri, '{}_{}.ply'.format(img_fp.replace(suffix, ''), ind)) if is_dump_vertex: dump_vertex( vertices, '{}_{}.mat'.format(img_fp.replace(suffix, ''), ind)) if is_dump_pts: wfp = '{}_{}.txt'.format(img_fp.replace(suffix, ''), ind) np.savetxt(wfp, pts68, fmt='%.3f') print('Save 68 3d landmarks to {}'.format(wfp)) if is_dump_roi_box: wfp = '{}_{}.roibox'.format(img_fp.replace(suffix, ''), ind) np.savetxt(wfp, roi_box, fmt='%.3f') print('Save roi box to {}'.format(wfp)) if is_dump_paf: wfp_paf = '{}_{}_paf.jpg'.format(img_fp.replace(suffix, ''), ind) wfp_crop = '{}_{}_crop.jpg'.format(img_fp.replace(suffix, ''), ind) paf_feature = gen_img_paf(img_crop=img, param=param, kernel_size=paf_size) cv2.imwrite(wfp_paf, paf_feature) cv2.imwrite(wfp_crop, img) print('Dump to {} and {}'.format(wfp_crop, wfp_paf)) if is_dump_obj: wfp = '{}_{}.obj'.format(img_fp.replace(suffix, ''), ind) colors = get_colors(img_ori, vertices) write_obj_with_colors(wfp, vertices, tri, colors) print('Dump obj with sampled texture to {}'.format(wfp)) ind += 1 if is_dump_pose: # P, pose = parse_pose(param) # Camera matrix (without scale), and pose (yaw, pitch, roll, to verify) img_pose = plot_pose_box(img_ori, Ps, pts_res) wfp = img_fp.replace(suffix, '_pose.jpg') cv2.imwrite(wfp, img_pose) print('Dump to {}'.format(wfp)) if is_dump_depth: wfp = img_fp.replace(suffix, '_depth.png') # depths_img = get_depths_image(img_ori, vertices_lst, tri-1) # python version depths_img = cget_depths_image(img_ori, vertices_lst, tri - 1) # cython version cv2.imwrite(wfp, depths_img) print('Dump to {}'.format(wfp)) if is_dump_pncc: wfp = img_fp.replace(suffix, '_pncc.png') pncc_feature = cpncc(img_ori, vertices_lst, tri - 1) # cython version cv2.imwrite( wfp, pncc_feature[:, :, ::-1]) # cv2.imwrite will swap RGB -> BGR print('Dump to {}'.format(wfp)) if is_dump_res: draw_landmarks(img_ori, pts_res, wfp=img_fp.replace(suffix, '_3DDFA.jpg'), show_flg=show_landmarks_fig) # 下面这一句将原始图像关掉 img_ori = np.ones_like(img_ori) * 255 img_pose = plot_pose_box(img_ori, Ps, pts_res) draw_landmarks_opencv(img_pose, pts_res) cv2.imshow("pose", img_pose)
def main(args): if args.isShow or args.isTexture: import cv2 from utils.cv_plot import plot_kpt, plot_vertices, plot_pose_box # ---- init PRN os.environ['CUDA_VISIBLE_DEVICES'] = args.gpu # GPU number, -1 for CPU prn = PRN(is_dlib = args.isDlib) # ------------- load data image_folder = args.inputDir print(image_folder) save_folder = args.outputDir print(save_folder) if not os.path.exists(save_folder): os.mkdir(save_folder) meta_save_folder = os.path.join(save_folder, 'meta') if not os.path.exists(meta_save_folder): os.mkdir(meta_save_folder) types = ('*.jpg', '*.png', '*,JPG') image_path_list= find_files(image_folder, ('.jpg', '.png', '.JPG')) total_num = len(image_path_list) print(image_path_list) for i, image_path in enumerate(image_path_list): name = image_path.strip().split('/')[-1][:-4] print(image_path) # read image image = imread(image_path) [h, w, c] = image.shape if c>3: image = image[:,:,:3] # the core: regress position map if args.isDlib: max_size = max(image.shape[0], image.shape[1]) if max_size> 1000: image = rescale(image, 1000./max_size) image = (image*255).astype(np.uint8) pos = prn.process(image) # use dlib to detect face else: if image.shape[1] == image.shape[2]: image = resize(image, (256,256)) pos = prn.net_forward(image/255.) # input image has been cropped to 256x256 else: box = np.array([0, image.shape[1]-1, 0, image.shape[0]-1]) # cropped with bounding box pos = prn.process(image, box) image = image/255. if pos is None: continue if args.is3d or args.isMat or args.isPose or args.isShow: # 3D vertices vertices = prn.get_vertices(pos) if args.isFront: save_vertices = frontalize(vertices) else: save_vertices = vertices.copy() save_vertices[:,1] = h - 1 - save_vertices[:,1] if args.isImage: imsave(os.path.join(save_folder, name + '.jpg'), image) if args.is3d: # corresponding colors colors = prn.get_colors(image, vertices) if args.isTexture: if args.texture_size != 256: pos_interpolated = resize(pos, (args.texture_size, args.texture_size), preserve_range = True) else: pos_interpolated = pos.copy() texture = cv2.remap(image, pos_interpolated[:,:,:2].astype(np.float32), None, interpolation=cv2.INTER_LINEAR, borderMode=cv2.BORDER_CONSTANT,borderValue=(0)) if args.isMask: vertices_vis = get_visibility(vertices, prn.triangles, h, w) uv_mask = get_uv_mask(vertices_vis, prn.triangles, prn.uv_coords, h, w, prn.resolution_op) uv_mask = resize(uv_mask, (args.texture_size, args.texture_size), preserve_range = True) texture = texture*uv_mask[:,:,np.newaxis] write_obj_with_texture(os.path.join(save_folder, name + '.obj'), save_vertices, prn.triangles, texture, prn.uv_coords/prn.resolution_op)#save 3d face with texture(can open with meshlab) else: write_obj_with_colors(os.path.join(save_folder, name + '.obj'), save_vertices, prn.triangles, colors) #save 3d face(can open with meshlab) if args.isDepth: depth_image = get_depth_image(vertices, prn.triangles, h, w, True) depth = get_depth_image(vertices, prn.triangles, h, w) imsave(os.path.join(save_folder, name + '_depth.jpg'), depth_image) sio.savemat(os.path.join(meta_save_folder, name + '_depth.mat'), {'depth':depth}) if args.isMat: sio.savemat(os.path.join(meta_save_folder, name + '_mesh.mat'), {'vertices': vertices, 'colors': colors, 'triangles': prn.triangles}) if args.isKpt or args.isShow: # get landmarks kpt = prn.get_landmarks(pos) # pdb.set_trace() np.save(os.path.join(meta_save_folder, name + '_kpt.npy'), kpt) # cv2.imwrite(os.path.join(save_folder, name + '_skpt.jpg'), plot_kpt(image, kpt)) if args.isPose or args.isShow: # estimate pose camera_matrix, pose = estimate_pose(vertices) np.savetxt(os.path.join(meta_save_folder, name + '_pose.txt'), pose) np.savetxt(os.path.join(meta_save_folder, name + '_camera_matrix.txt'), camera_matrix) if args.isShow: # ---------- Plot image = imread(os.path.join(save_folder, name + '.jpg')) image_pose = plot_pose_box(image, camera_matrix, kpt) #cv2.imwrite(os.path.join(save_folder, name + '_pose.jpg'), plot_kpt(image, kpt)) #cv2.imwrite(os.path.join(save_folder, name + '_camera_matrix.jpg'), plot_vertices(image, vertices)) #cv2.imwrite(os.path.join(save_folder, name + '_pose.jpg'), plot_pose_box(image, camera_matrix, kpt)) image = imread(os.path.join(save_folder, name + '.jpg')) b, g, r = cv2.split(image) image = cv2.merge([r,g,b])
def main(args): if args.isShow or args.isTexture or args.isCamera: import cv2 from utils.cv_plot import plot_kpt, plot_vertices, plot_pose_box # ---- init PRN os.environ['CUDA_VISIBLE_DEVICES'] = args.gpu # GPU number, -1 for CPU prn = PRN(is_dlib=args.isDlib) # ------------- load data image_folder = args.inputDir save_folder = args.outputDir if not os.path.exists(save_folder): os.mkdir(save_folder) types = ('*.jpg', '*.png') image_path_list = [] for files in types: image_path_list.extend(glob(os.path.join(image_folder, files))) total_num = len(image_path_list) if args.isCamera: # Create a VideoCapture object and read from input file # If the input is the camera, pass 0 instead of the video file name cap = cv2.VideoCapture(0) # Check if camera opened successfully if (cap.isOpened() == False): print("Error opening video stream or file") # Read until video is completed while (cap.isOpened()): # Capture frame-by-frame ret, frame = cap.read() if ret == True: if args.isDlib: max_size = max(frame.shape[0], frame.shape[1]) if max_size > 1000: frame = rescale(frame, 1000. / max_size) frame = (frame * 255).astype(np.uint8) pos = prn.process(frame) # use dlib to detect face else: if frame.shape[0] == frame.shape[1]: frame = resize(frame, (256, 256)) pos = prn.net_forward( frame / 255.) # input frame has been cropped to 256x256 else: box = np.array( [0, frame.shape[1] - 1, 0, frame.shape[0] - 1]) # cropped with bounding box pos = prn.process(frame, box) # Normalizing the frame and skiping if there was no one in the frame frame = frame / 255. if pos is None: continue # Get landmarks in frame kpt = prn.get_landmarks(pos) # Display the resulting frame cv2.imshow('sparse alignment', plot_kpt(frame, kpt)) # Press Q on keyboard to exit if cv2.waitKey(25) & 0xFF == ord('q'): break # Break the loop else: break # When everything done, release the video capture object cap.release() # Closes all the frames cv2.destroyAllWindows() else: for i, image_path in enumerate(image_path_list): name = image_path.strip().split('/')[-1][:-4] # read image image = imread(image_path) [h, w, c] = image.shape if c > 3: image = image[:, :, :3] # the core: regress position map if args.isDlib: max_size = max(image.shape[0], image.shape[1]) if max_size > 1000: image = rescale(image, 1000. / max_size) image = (image * 255).astype(np.uint8) pos = prn.process(image) # use dlib to detect face else: if image.shape[0] == image.shape[1]: image = resize(image, (256, 256)) pos = prn.net_forward( image / 255.) # input image has been cropped to 256x256 else: box = np.array( [0, image.shape[1] - 1, 0, image.shape[0] - 1]) # cropped with bounding box pos = prn.process(image, box) image = image / 255. if pos is None: continue if args.is3d or args.isMat or args.isPose or args.isShow: # 3D vertices vertices = prn.get_vertices(pos) if args.isFront: save_vertices = frontalize(vertices) else: save_vertices = vertices.copy() save_vertices[:, 1] = h - 1 - save_vertices[:, 1] if args.isImage: imsave(os.path.join(save_folder, name + '.jpg'), image) if args.is3d: # corresponding colors colors = prn.get_colors(image, vertices) if args.isTexture: if args.texture_size != 256: pos_interpolated = resize( pos, (args.texture_size, args.texture_size), preserve_range=True) else: pos_interpolated = pos.copy() texture = cv2.remap(image, pos_interpolated[:, :, :2].astype( np.float32), None, interpolation=cv2.INTER_LINEAR, borderMode=cv2.BORDER_CONSTANT, borderValue=(0)) if args.isMask: vertices_vis = get_visibility(vertices, prn.triangles, h, w) uv_mask = get_uv_mask(vertices_vis, prn.triangles, prn.uv_coords, h, w, prn.resolution_op) uv_mask = resize( uv_mask, (args.texture_size, args.texture_size), preserve_range=True) texture = texture * uv_mask[:, :, np.newaxis] write_obj_with_texture( os.path.join(save_folder, name + '.obj'), save_vertices, prn.triangles, texture, prn.uv_coords / prn.resolution_op ) #save 3d face with texture(can open with meshlab) else: write_obj_with_colors( os.path.join(save_folder, name + '.obj'), save_vertices, prn.triangles, colors) #save 3d face(can open with meshlab) if args.isDepth: depth_image = get_depth_image(vertices, prn.triangles, h, w, True) depth = get_depth_image(vertices, prn.triangles, h, w) imsave(os.path.join(save_folder, name + '_depth.jpg'), depth_image) sio.savemat(os.path.join(save_folder, name + '_depth.mat'), {'depth': depth}) if args.isMat: sio.savemat( os.path.join(save_folder, name + '_mesh.mat'), { 'vertices': vertices, 'colors': colors, 'triangles': prn.triangles }) if args.isKpt or args.isShow: # get landmarks kpt = prn.get_landmarks(pos) np.savetxt(os.path.join(save_folder, name + '_kpt.txt'), kpt) if args.isPose or args.isShow: # estimate pose camera_matrix, pose = estimate_pose(vertices) np.savetxt(os.path.join(save_folder, name + '_pose.txt'), pose) np.savetxt( os.path.join(save_folder, name + '_camera_matrix.txt'), camera_matrix) np.savetxt(os.path.join(save_folder, name + '_pose.txt'), pose) if args.isShow: # ---------- Plot image_pose = plot_pose_box(image, camera_matrix, kpt) cv2.imshow( 'sparse alignment', cv2.cvtColor(np.float32(plot_kpt(image, kpt)), cv2.COLOR_RGB2BGR)) cv2.imshow( 'dense alignment', cv2.cvtColor(np.float32(plot_vertices(image, vertices)), cv2.COLOR_RGB2BGR)) cv2.imshow( 'pose', cv2.cvtColor( np.float32(plot_pose_box(image, camera_matrix, kpt)), cv2.COLOR_RGB2BGR)) cv2.waitKey(0)
def classify(model, inputs): in_img = inputs['content_image'] img_ori = np.array(in_img) img_fp = 'samples/test1.jpg' face_detector = dlib.get_frontal_face_detector() # 3. forward tri = sio.loadmat('visualize/tri.mat')['tri'] transform = transforms.Compose( [ToTensorGjz(), NormalizeGjz(mean=127.5, std=128)]) #print(transform) rects = face_detector(img_ori, 1) pts_res = [] Ps = [] # Camera matrix collection poses = [] # pose collection, [todo: validate it] vertices_lst = [] # store multiple face vertices ind = 0 suffix = get_suffix(img_fp) for rect in rects: # - use detected face bbox bbox = [rect.left(), rect.top(), rect.right(), rect.bottom()] roi_box = parse_roi_box_from_bbox(bbox) img = crop_img(img_ori, roi_box) # forward: one step img = cv2.resize(img, dsize=(STD_SIZE, STD_SIZE), interpolation=cv2.INTER_LINEAR) input = transform(img).unsqueeze(0) with torch.no_grad(): if mode == 'gpu': input = input.cuda() param = model(input) param = param.squeeze().cpu().numpy().flatten().astype(np.float32) # 68 pts pts68 = predict_68pts(param, roi_box) # two-step for more accurate bbox to crop face if bbox_init == 'two': roi_box = parse_roi_box_from_landmark(pts68) img_step2 = crop_img(img_ori, roi_box) img_step2 = cv2.resize(img_step2, dsize=(STD_SIZE, STD_SIZE), interpolation=cv2.INTER_LINEAR) input = transform(img_step2).unsqueeze(0) with torch.no_grad(): if mode == 'gpu': input = input.cuda() param = model(input) param = param.squeeze().cpu().numpy().flatten().astype( np.float32) pts68 = predict_68pts(param, roi_box) pts_res.append(pts68) P, pose = parse_pose(param) Ps.append(P) poses.append(pose) vertices = predict_dense(param, roi_box) vertices_lst.append(vertices) ind += 1 if inputs['output_type'] == 'pose': the_output = plot_pose_box(img_ori, Ps, pts_res) if inputs['output_type'] == 'depth': pncc_feature = cpncc(img_ori, vertices_lst, tri - 1) output = pncc_feature[:, :, ::-1] the_output = transforms.ToPILImage()(np.uint8(output)) if inputs['output_type'] == 'points': the_output = draw_landmarks(img_ori, pts_res, show_flg=show_flg) if inputs['output_type'] == 'skin': the_output = gen_img_paf(img_crop=img, param=param, kernel_size=paf_size) return {"image": the_output}