EasyMocap/myeasymocap/datasets/basedata.py

106 lines
4.1 KiB
Python
Raw Normal View History

2023-06-19 16:39:27 +08:00
import os
from os.path import join
import numpy as np
import cv2
from easymocap.mytools.debug_utils import log, myerror, mywarn
class ImageDataBase:
def __init__(self, root, subs, ranges, read_image) -> None:
assert root != 'TO_BE_FILLED', 'You must set the root of dataset'
assert os.path.exists(root), f'root {root} not exists'
self.root = root
self.subs = subs
self.ranges = ranges
self.flag_read_image = read_image
self.infos = {}
self.meta = {}
def check_frames_length(self):
if len(self.ranges) == 0:
self.ranges = [0, self.length, 1]
if self.ranges[1] > self.length:
self.ranges[1] = self.length
self.frames = list(range(*self.ranges))
self.length = len(self.frames)
def try_to_extract_images(self, root, value):
if not os.path.exists(os.path.join(root, value['root'])) and os.path.exists(os.path.join(root, 'videos')):
print('[{}] Cannot find the images but find the videos, try to extract it'.format(self.__class__.__name__))
for videoname in os.listdir(os.path.join(root, 'videos')):
videoext = '.' + videoname.split('.')[-1]
outdir = join(root, value['root'], videoname.replace(videoext, ''))
os.makedirs(outdir, exist_ok=True)
cmd = 'ffmpeg -i {videoname} -q:v 1 -start_number 0 {outdir}/%06d.jpg'.format(
videoname=join(root, 'videos', videoname),
outdir=outdir
)
os.system(cmd)
def __str__(self) -> str:
return f''' [Dataset] {self.__class__.__name__}
root : {self.root}
subs : {self.subs}
ranges: {self.ranges}
'''
def __getitem__(self, index):
raise NotImplementedError
def __len__(self):
return self.length
def read_image(self, imgname, cameras=None):
assert os.path.exists(imgname), "image {} not exists".format(imgname)
sub = os.path.basename(os.path.dirname(imgname))
img = cv2.imread(imgname)
if cameras is None:
return img
K, D = self.cameras[sub]['K'], self.cameras[sub]['dist']
if np.linalg.norm(D) < 1e-3:
return img
if sub not in self.distortMap.keys():
h, w = img.shape[:2]
mapx, mapy = cv2.initUndistortRectifyMap(K, D, None, K, (w,h), 5)
self.distortMap[sub] = (mapx, mapy)
mapx, mapy = self.distortMap[sub]
img = cv2.remap(img, mapx, mapy, cv2.INTER_NEAREST)
return img
def read_mv_images(root, root_images, ext, subs):
assert os.path.exists(os.path.join(root, root_images)), f'root {root}/{root_images} not exists'
if len(subs) == 0:
subs = sorted(os.listdir(os.path.join(root, root_images)))
if subs[0].isdigit():
subs = sorted(subs, key=lambda x: int(x))
imagelists = []
log(f'Found {len(subs)} subjects in {root}/{root_images}')
for sub in subs:
images = sorted(os.listdir(os.path.join(root, root_images, sub)))
images = [os.path.join(root, root_images, sub, image) for image in images if image.endswith(ext)]
log(f' -> Found {len(images)} {root_images} in {sub}.')
imagelists.append(images)
min_length = min([len(image) for image in imagelists])
log(f' -> Min length: {min_length}')
imagenames = [[image[i] for image in imagelists] for i in range(min_length)]
return imagenames, {'subs': subs}
def FloatArray(x):
return np.array(x, dtype=np.float32)
def find_best_people(annots):
if len(annots) == 0:
return {}
# TODO: find the best
annot = annots[0]
bbox = FloatArray(annot['bbox'])
if 'keypoints' not in annot.keys():
return {}
keypoints = FloatArray(annot['keypoints'])
return {'bbox': bbox, 'keypoints': keypoints}
def find_all_people(annots):
if len(annots) == 0:
return {}
bbox = FloatArray([annot['bbox'] for annot in annots])
keypoints = FloatArray([annot['keypoints'] for annot in annots])
return {'bbox': bbox, 'keypoints': keypoints}