From 0214f5e5413434ca23750616b00a5c07f86dd020 Mon Sep 17 00:00:00 2001 From: shuaiqing Date: Fri, 18 Jun 2021 15:47:26 +0800 Subject: [PATCH] [mv1p] add write_smpl_full --- apps/demo/mv1p.py | 14 +++++++++--- easymocap/mytools/cmd_loader.py | 10 +++++++-- easymocap/mytools/file_utils.py | 29 ++++++++++++++++++++---- easymocap/mytools/reader.py | 39 +++++++++++++++++++++++++++++---- easymocap/mytools/utils.py | 15 +++++++++++-- 5 files changed, 92 insertions(+), 15 deletions(-) diff --git a/apps/demo/mv1p.py b/apps/demo/mv1p.py index e45d88e..75068b0 100644 --- a/apps/demo/mv1p.py +++ b/apps/demo/mv1p.py @@ -2,8 +2,8 @@ @ Date: 2021-04-13 19:46:51 @ Author: Qing Shuai @ LastEditors: Qing Shuai - @ LastEditTime: 2021-04-14 11:33:00 - @ FilePath: /EasyMocapRelease/apps/demo/mv1p.py + @ LastEditTime: 2021-06-13 17:56:25 + @ FilePath: /EasyMocap/apps/demo/mv1p.py ''' from tqdm import tqdm from easymocap.smplmodel import check_keypoints, load_model, select_nf @@ -75,13 +75,21 @@ def mv1pmf_smpl(dataset, args, weight_pose=None, weight_shape=None): images, annots = dataset[nf] param = select_nf(params, nf-start) dataset.write_smpl(param, nf) + if args.write_smpl_full: + param_full = param.copy() + param_full['poses'] = body_model.full_poses(param['poses']) + dataset.write_smpl(param_full, nf, mode='smpl_full') + if args.write_vertices: + vertices = body_model(return_verts=True, return_tensor=False, **param) + write_data = [{'id': 0, 'vertices': vertices[0]}] + dataset.write_vertices(write_data, nf) if args.vis_smpl: vertices = body_model(return_verts=True, return_tensor=False, **param) dataset.vis_smpl(vertices=vertices[0], faces=body_model.faces, images=images, nf=nf, sub_vis=args.sub_vis, add_back=True) if args.vis_repro: keypoints = body_model(return_verts=False, return_tensor=False, **param)[0] kpts_repro = projectN3(keypoints, dataset.Pall) - dataset.vis_repro(images, kpts_repro, nf=nf, sub_vis=args.sub_vis) + dataset.vis_repro(images, kpts_repro, nf=nf, sub_vis=args.sub_vis, mode='repro_smpl') if __name__ == "__main__": from easymocap.mytools import load_parser, parse_parser diff --git a/easymocap/mytools/cmd_loader.py b/easymocap/mytools/cmd_loader.py index 47d06fb..3187c29 100644 --- a/easymocap/mytools/cmd_loader.py +++ b/easymocap/mytools/cmd_loader.py @@ -2,7 +2,7 @@ @ Date: 2021-01-15 12:09:27 @ Author: Qing Shuai @ LastEditors: Qing Shuai - @ LastEditTime: 2021-06-09 19:52:41 + @ LastEditTime: 2021-06-15 11:09:36 @ FilePath: /EasyMocap/easymocap/mytools/cmd_loader.py ''' import os @@ -31,6 +31,7 @@ def load_parser(): # # keypoints and body model # + parser.add_argument('--cfg_model', type=str, default=None) parser.add_argument('--body', type=str, default='body25', choices=['body15', 'body25', 'h36m', 'bodyhand', 'bodyhandface', 'handl', 'handr', 'total']) parser.add_argument('--model', type=str, default='smpl', choices=['smpl', 'smplh', 'smplx', 'manol', 'manor']) parser.add_argument('--gender', type=str, default='neutral', @@ -58,6 +59,7 @@ def load_parser(): output.add_argument('--vis_repro', action='store_true') output.add_argument('--vis_smpl', action='store_true') output.add_argument('--write_smpl_full', action='store_true') + parser.add_argument('--write_vertices', action='store_true') output.add_argument('--vis_mask', action='store_true') output.add_argument('--undis', action='store_true') output.add_argument('--sub_vis', type=str, nargs='+', default=[], @@ -73,7 +75,11 @@ def load_parser(): parser.add_argument('--opts', help="Modify config options using the command-line", default=[], - nargs=argparse.REMAINDER) + nargs='+') + parser.add_argument('--cfg_opts', + help="Modify config options using the command-line", + default=[], + nargs='+') return parser from os.path import join diff --git a/easymocap/mytools/file_utils.py b/easymocap/mytools/file_utils.py index ed5c48c..b3cd0d6 100644 --- a/easymocap/mytools/file_utils.py +++ b/easymocap/mytools/file_utils.py @@ -2,7 +2,7 @@ @ Date: 2021-03-15 12:23:12 @ Author: Qing Shuai @ LastEditors: Qing Shuai - @ LastEditTime: 2021-05-27 20:50:43 + @ LastEditTime: 2021-06-14 22:25:58 @ FilePath: /EasyMocapRelease/easymocap/mytools/file_utils.py ''' import os @@ -25,6 +25,8 @@ def save_json(file, data): with open(file, 'w') as f: json.dump(data, f, indent=4) +save_annot = save_json + def getFileList(root, ext='.jpg'): files = [] dirs = os.listdir(root) @@ -89,14 +91,15 @@ def array2raw(array, separator=' ', fmt='%.3f'): res.append(separator.join([fmt%(d) for d in data])) -def myarray2string(array, separator=', ', fmt='%.3f'): +def myarray2string(array, separator=', ', fmt='%.3f', indent=8): assert len(array.shape) == 2, 'Only support MxN matrix, {}'.format(array.shape) + blank = ' ' * indent res = ['['] for i in range(array.shape[0]): - res.append(' [{}]'.format(separator.join([fmt%(d) for d in array[i]]))) + res.append(blank + ' ' + '[{}]'.format(separator.join([fmt%(d) for d in array[i]]))) if i != array.shape[0] -1: res[-1] += ', ' - res.append(' ]') + res.append(blank + ']') return '\r\n'.join(res) def write_common_results(dumpname=None, results=[], keys=[], fmt='%2.3f'): @@ -144,6 +147,24 @@ def write_smpl(dumpname, results): keys = ['Rh', 'Th', 'poses', 'expression', 'shapes'] write_common_results(dumpname, results, keys) +def batch_bbox_from_pose(keypoints2d, height, width, rate=0.1): + # TODO:write this in batch + bboxes = np.zeros((keypoints2d.shape[0], 5), dtype=np.float32) + border = 20 + for bn in range(keypoints2d.shape[0]): + valid = keypoints2d[bn, :, -1] > 0 + if valid.sum() == 0: + continue + p2d = keypoints2d[bn, valid, :2] + x_min, y_min = p2d.min(axis=0) + x_max, y_max = p2d.max(axis=0) + x_mean, y_mean = p2d.mean(axis=0) + if x_mean < -border or y_mean < -border or x_mean > width + border or y_mean > height + border: + continue + dx = (x_max - x_min)*rate + dy = (y_max - y_min)*rate + bboxes[bn] = [x_min-dx, y_min-dy, x_max+dx, y_max+dy, 1] + return bboxes def get_bbox_from_pose(pose_2d, img=None, rate = 0.1): # this function returns bounding box from the 2D pose diff --git a/easymocap/mytools/reader.py b/easymocap/mytools/reader.py index 7575a2e..36d205b 100644 --- a/easymocap/mytools/reader.py +++ b/easymocap/mytools/reader.py @@ -1,3 +1,10 @@ +''' + @ Date: 2021-04-21 15:19:21 + @ Author: Qing Shuai + @ LastEditors: Qing Shuai + @ LastEditTime: 2021-06-15 11:30:00 + @ FilePath: /EasyMocap/easymocap/mytools/reader.py +''' # function to read data """ This class provides: @@ -7,10 +14,13 @@ - smpl | x | o """ import numpy as np -from .file_utils import read_json +import os +from os.path import join +from glob import glob +from .file_utils import read_json, read_annot -def read_keypoints2d(filename): - pass +def read_keypoints2d(filename, mode): + return read_annot(filename, mode) def read_keypoints3d(filename): data = read_json(filename) @@ -56,4 +66,25 @@ def read_keypoints3d_a4d(outname): # association4d 的关节顺序和正常的定义不一样 pose3d = pose3d[[4, 1, 5, 9, 13, 6, 10, 14, 0, 2, 7, 11, 3, 8, 12], :] res_.append({'id':trackId, 'keypoints3d':np.array(pose3d)}) - return res_ \ No newline at end of file + return res_ + +def read_keypoints3d_all(path, key='keypoints3d', pids=[]): + assert os.path.exists(path), '{} not exists!'.format(path) + results = {} + filenames = sorted(glob(join(path, '*.json'))) + for filename in filenames: + nf = int(os.path.basename(filename).replace('.json', '')) + datas = read_keypoints3d(filename) + for data in datas: + pid = data['id'] + if len(pids) > 0 and pid not in pids: + continue + # 注意 这里没有考虑从哪开始的 + if pid not in results.keys(): + results[pid] = {key: [], 'frames': []} + results[pid][key].append(data[key]) + results[pid]['frames'].append(nf) + if key == 'keypoints3d': + for pid, result in results.items(): + result[key] = np.stack(result[key]) + return results, filenames \ No newline at end of file diff --git a/easymocap/mytools/utils.py b/easymocap/mytools/utils.py index 339c54a..b4ea0bb 100644 --- a/easymocap/mytools/utils.py +++ b/easymocap/mytools/utils.py @@ -2,13 +2,24 @@ @ Date: 2021-01-15 11:12:00 @ Author: Qing Shuai @ LastEditors: Qing Shuai - @ LastEditTime: 2021-05-27 14:55:40 + @ LastEditTime: 2021-06-16 14:05:39 @ FilePath: /EasyMocap/easymocap/mytools/utils.py ''' import time import tabulate class Timer: records = {} + tmp = None + + @classmethod + def tic(cls): + cls.tmp = time.time() + @classmethod + def toc(cls): + res = (time.time() - cls.tmp) * 1000 + cls.tmp = None + return res + @classmethod def report(cls): header = ['', 'Time(ms)'] @@ -16,7 +27,7 @@ class Timer: for key, val in cls.records.items(): contents.append(['{:20s}'.format(key), '{:.2f}'.format(sum(val)/len(val))]) print(tabulate.tabulate(contents, header, tablefmt='fancy_grid')) - + def __init__(self, name, silent=False): self.name = name self.silent = silent