from operator import imod import numpy as np from tqdm import tqdm from os.path import join from easymocap.dataset.mv1pmf_mirror import ImageFolderMirror as ImageFolder from easymocap.mytools import Timer from easymocap.smplmodel import load_model, merge_params, select_nf from easymocap.estimator import SPIN, init_with_spin from easymocap.pipeline.mirror import multi_stage_optimize def demo_1v1p1f_smpl_mirror(path, body_model, spin_model, args): "Optimization for single image" # 0. construct the dataset dataset = ImageFolder(path, out=args.out, kpts_type=args.body) if args.gtK: dataset.gtK = True dataset.load_gt_cameras() start, end = args.start, min(args.end, len(dataset)) for nf in tqdm(range(start, end, args.step), desc='Optimizing'): image, annots = dataset[nf] if len(annots) < 2: continue annots = annots[:2] camera = dataset.camera(nf) # initialize the SMPL parameters body_params_all = [] bboxes, keypoints2d, pids = [], [], [] for i, annot in enumerate(annots): assert annot['id'] == i, (i, annot['id']) result = init_with_spin(body_model, spin_model, image, annot['bbox'], annot['keypoints'], camera) body_params_all.append(result['body_params']) bboxes.append(annot['bbox']) keypoints2d.append(annot['keypoints']) pids.append(annot['id']) bboxes = np.vstack(bboxes) keypoints2d = np.stack(keypoints2d) body_params = merge_params(body_params_all) # bboxes: (nViews(2), 1, 5); keypoints2d: (nViews(2), 1, nJoints, 3) bboxes = bboxes[:, None] keypoints2d = keypoints2d[:, None] if args.normal: normal = dataset.normal(nf)[None, :, :] else: normal = None body_params = multi_stage_optimize(body_model, body_params, bboxes, keypoints2d, Pall=camera['P'], normal=normal, args=args) vertices = body_model(return_verts=True, return_tensor=False, **body_params) keypoints = body_model(return_verts=False, return_tensor=False, **body_params) write_data = [{'id': pids[i], 'keypoints3d': keypoints[i]} for i in range(len(pids))] # write out the results dataset.write_keypoints3d(write_data, nf) for i in range(len(pids)): write_data[i].update(select_nf(body_params, i)) if args.vis_smpl: # render the results render_data = {pids[i]: { 'vertices': vertices[i], 'faces': body_model.faces, 'vid': 0, 'name': 'human_{}'.format(pids[i])} for i in range(len(pids))} dataset.vis_smpl(render_data, image, camera, nf) dataset.write_smpl(write_data, nf) def demo_1v1pmf_smpl_mirror(path, body_model, spin_model, args): subs = args.sub assert len(subs) > 0 # 遍历所有文件夹 for sub in subs: dataset = ImageFolder(path, subs=[sub], out=args.out, kpts_type=args.body) start, end = args.start, min(args.end, len(dataset)) frames = list(range(start, end, args.step)) nFrames = len(frames) pids = [0, 1] body_params_all = {pid:[None for nf in frames] for pid in pids} bboxes = {pid:[None for nf in frames] for pid in pids} keypoints2d = {pid:[None for nf in frames] for pid in pids} for nf in tqdm(frames, desc='loading'): image, annots = dataset[nf] # 这个时候如果annots不够 不能够跳过了,需要进行补全 camera = dataset.camera(nf) # 初始化每个人的SMPL参数 for i, annot in enumerate(annots): pid = annot['id'] if pid not in pids: continue result = init_with_spin(body_model, spin_model, image, annot['bbox'], annot['keypoints'], camera) body_params_all[pid][nf-start] = result['body_params'] bboxes[pid][nf-start] = annot['bbox'] keypoints2d[pid][nf-start] = annot['keypoints'] # stack [p1f1, p1f2, p1f3, ..., p1fn, p2f1, p2f2, p2f3, ..., p2fn] # TODO:for missing bbox body_params = merge_params([merge_params(body_params_all[pid]) for pid in pids]) # bboxes: (nViews, nFrames, 5) bboxes = np.stack([np.stack(bboxes[pid]) for pid in pids]) # keypoints: (nViews, nFrames, nJoints, 3) keypoints2d = np.stack([np.stack(keypoints2d[pid]) for pid in pids]) # optimize P = dataset.camera(start)['P'] if args.normal: normal = dataset.normal_all(start=start, end=end) else: normal = None body_params = multi_stage_optimize(body_model, body_params, bboxes, keypoints2d, Pall=P, normal=normal, args=args) # write vertices = body_model(return_verts=True, return_tensor=False, **body_params) keypoints = body_model(return_verts=False, return_tensor=False, **body_params) dataset.no_img = not args.vis_smpl for nf in tqdm(frames, desc='rendering'): idx = nf - start write_data = [{'id': pids[i], 'keypoints3d': keypoints[i*nFrames+idx]} for i in range(len(pids))] dataset.write_keypoints3d(write_data, nf) for i in range(len(pids)): write_data[i].update(select_nf(body_params, i*nFrames+idx)) dataset.write_smpl(write_data, nf) # 保存结果 if args.vis_smpl: image, annots = dataset[nf] camera = dataset.camera(nf) render_data = {pids[i]: { 'vertices': vertices[i*nFrames+idx], 'faces': body_model.faces, 'vid': 0, 'name': 'human_{}'.format(pids[i])} for i in range(len(pids))} dataset.vis_smpl(render_data, image, camera, nf) if __name__ == "__main__": from easymocap.mytools import load_parser, parse_parser parser = load_parser() parser.add_argument('--skel', type=str, default=None, help='path to keypoints3d') parser.add_argument('--direct', action='store_true') parser.add_argument('--video', action='store_true') parser.add_argument('--gtK', action='store_true') parser.add_argument('--normal', action='store_true', help='set to use the normal of the mirror') args = parse_parser(parser) helps = ''' Demo code for single view and one person with mirror: - Input : {}: [{}] - Output: {} - Body : {} => {}, {} '''.format(args.path, ', '.join(args.sub), args.out, args.model, args.gender, args.body) print(helps) with Timer('Loading {}, {}'.format(args.model, args.gender)): body_model = load_model(args.gender, model_type=args.model) with Timer('Loading SPIN'): spin_model = SPIN( SMPL_MEAN_PARAMS='data/models/smpl_mean_params.npz', checkpoint='data/models/spin_checkpoint.pt', device=body_model.device) if args.video: demo_1v1pmf_smpl_mirror(args.path, body_model, spin_model, args) else: demo_1v1p1f_smpl_mirror(args.path, body_model, spin_model, args)