154 lines
5.9 KiB
Python
154 lines
5.9 KiB
Python
'''
|
|
@ Date: 2021-06-09 10:16:46
|
|
@ Author: Qing Shuai
|
|
@ LastEditors: Qing Shuai
|
|
@ LastEditTime: 2022-10-21 16:55:26
|
|
@ FilePath: /EasyMocapPublic/easymocap/annotator/file_utils.py
|
|
'''
|
|
import os
|
|
import json
|
|
import numpy as np
|
|
from os.path import join
|
|
import shutil
|
|
from ..mytools.file_utils import myarray2string
|
|
|
|
def read_json(path):
|
|
with open(path, 'r') as f:
|
|
data = json.load(f)
|
|
return data
|
|
|
|
def save_json(file, data):
|
|
if file is None:
|
|
return 0
|
|
if not os.path.exists(os.path.dirname(file)):
|
|
os.makedirs(os.path.dirname(file))
|
|
with open(file, 'w') as f:
|
|
json.dump(data, f, indent=4)
|
|
|
|
tobool = lambda x: 'true' if x else 'false'
|
|
|
|
def annot2string(data):
|
|
out_text = []
|
|
out_text.append('{\n')
|
|
keysbase = ['filename', 'height', 'width', 'annots', 'isKeyframe']
|
|
keys_other = [key for key in data.keys() if key not in keysbase]
|
|
for key in keysbase[:-1] + keys_other + ['isKeyframe']:
|
|
value = data[key]
|
|
indent = 4
|
|
if key != 'annots':
|
|
if key == 'isKeyframe':
|
|
res = '"{}": {}'.format(key, tobool(value))
|
|
elif key == 'filename':
|
|
res = '"{}": "{}",'.format(key, value.replace('\\', "\\\\"))
|
|
elif isinstance(value, str):
|
|
res = '"{}": "{}",'.format(key, value)
|
|
elif isinstance(value, bool):
|
|
res = '"{}": {},'.format(key, tobool(value))
|
|
elif isinstance(value, int):
|
|
res = '"{}": {},'.format(key, value)
|
|
elif isinstance(value, np.ndarray):
|
|
#TODO: pretty array
|
|
res = '"{}": {},'.format(key, myarray2string(value, indent=0))
|
|
else:
|
|
res = '"{}": {},'.format(key, value)
|
|
out_text.append(indent * ' ' + res+'\n')
|
|
else:
|
|
out_text.append(indent * ' ' + '"annots": [\n')
|
|
for n, annot in enumerate(value):
|
|
head = (indent + 4) * " " + "{\n"
|
|
ind = (indent + 8) * " "
|
|
pid = ind + '"personID": {},\n'.format(annot['personID'])
|
|
out_text.append(head)
|
|
out_text.append(pid)
|
|
for ckey in ['class']:
|
|
if ckey not in annot.keys():
|
|
continue
|
|
info_class = ind + '"class": "{}",\n'.format(annot['class'])
|
|
out_text.append(info_class)
|
|
for bkey in ['bbox', 'bbox_handl2d', 'bbox_handr2d', 'bbox_face2d']:
|
|
if bkey not in annot.keys():
|
|
continue
|
|
bbox = ind + '"{}": [{:.2f}, {:.2f}, {:.2f}, {:.2f}, {:.2f}],\n'.format(bkey, *annot[bkey][:5])
|
|
out_text.append(bbox)
|
|
for bkey in ['keypoints', 'handl2d', 'handr2d', 'face2d', 'keypoints3d']:
|
|
if bkey not in annot.keys():
|
|
continue
|
|
val = np.array(annot[bkey])
|
|
conf = val[:, -1]
|
|
conf[conf<0] = 0
|
|
ret = myarray2string(val, fmt='%7.2f', indent=12)
|
|
kpts = ind + '"{}": '.format(bkey) + ret + ',\n'
|
|
out_text.append(kpts)
|
|
if 'params' in annot.keys():
|
|
out_text.append(ind + '"params": {\n')
|
|
keys = list(annot['params'].keys())
|
|
for vkey, val in annot['params'].items():
|
|
val = np.array(val)
|
|
ret = myarray2string(val, fmt='%7.2f', indent=4*4)
|
|
kpts = ind + 4*' ' + '"{}": '.format(vkey) + ret
|
|
if vkey == keys[-1]:
|
|
kpts += '\n'
|
|
else:
|
|
kpts += ',\n'
|
|
out_text.append(kpts)
|
|
out_text.append(ind + '},\n')
|
|
for rkey in ['isKeyframe']:
|
|
val = annot.get(rkey, False)
|
|
bkey = ind + '"{}": {}\n'.format(rkey, tobool(val))
|
|
tail = (indent + 4) * " " + "}"
|
|
if n == len(value) - 1:
|
|
tail += '\n'
|
|
else:
|
|
tail += ',\n'
|
|
out_text.extend([bkey, tail])
|
|
out_text.append(indent * ' ' + '],\n')
|
|
out_text.append('}\n')
|
|
out_text = ''.join(out_text)
|
|
return out_text
|
|
|
|
def save_annot(file, data):
|
|
if file is None:
|
|
return 0
|
|
if not os.path.exists(os.path.dirname(file)):
|
|
os.makedirs(os.path.dirname(file))
|
|
if 'filename' not in data.keys():
|
|
if data.get('isList', False):
|
|
data = data['annots']
|
|
save_json(file, data)
|
|
return 0
|
|
out_text = annot2string(data)
|
|
print(out_text, file=open(file, 'w'))
|
|
|
|
def getFileList(root, ext='.jpg', max=-1, ret_full=False):
|
|
files = []
|
|
dirs = sorted(os.listdir(root))
|
|
while len(dirs) > 0:
|
|
path = dirs.pop()
|
|
if path.startswith('.'):continue
|
|
fullname = join(root, path)
|
|
if os.path.isfile(fullname) and fullname.endswith(ext):
|
|
if ret_full:
|
|
files.append(fullname)
|
|
else:
|
|
files.append(path)
|
|
elif os.path.isdir(fullname):
|
|
names = sorted(os.listdir(fullname))
|
|
if max != -1 and os.path.isfile(join(fullname, names[0])):
|
|
names = names[:max]
|
|
for s in names:
|
|
newDir = join(path, s)
|
|
dirs.append(newDir)
|
|
files = sorted(files)
|
|
return files
|
|
|
|
def load_annot_to_tmp(annotname):
|
|
if annotname is None:
|
|
return {}
|
|
if not os.path.exists(annotname):
|
|
dirname = os.path.dirname(annotname)
|
|
os.makedirs(dirname, exist_ok=True)
|
|
shutil.copyfile(annotname.replace('_tmp', ''), annotname)
|
|
annot = read_json(annotname)
|
|
if isinstance(annot, list):
|
|
annot = {'annots': annot, 'isKeyframe': False, 'isList': True}
|
|
return annot |