123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191 |
- import argparse
- import os
- import os.path as osp
- import random
- import mmcv
- import numpy as np
- from mmengine.fileio import list_from_file
- from tqdm import tqdm
- USELESS = [3, 4, 5, 6, 9, 10, 11]
- IGNORES = [2, 7, 8, 12, 13]
- def parse_args():
- parser = argparse.ArgumentParser(
- description='Convert MOT dataset into ReID dataset.')
- parser.add_argument('-i', '--input', help='path of MOT data')
- parser.add_argument('-o', '--output', help='path to save ReID dataset')
- parser.add_argument(
- '--val-split',
- type=float,
- default=0.2,
- help='proportion of the validation dataset to the whole ReID dataset')
- parser.add_argument(
- '--vis-threshold',
- type=float,
- default=0.3,
- help='threshold of visibility for each person')
- parser.add_argument(
- '--min-per-person',
- type=int,
- default=8,
- help='minimum number of images for each person')
- parser.add_argument(
- '--max-per-person',
- type=int,
- default=1000,
- help='maxmum number of images for each person')
- return parser.parse_args()
- def main():
- args = parse_args()
- if not osp.isdir(args.output):
- os.makedirs(args.output, exist_ok=True)
- in_folder = osp.join(args.input, 'train')
- video_names = os.listdir(in_folder)
- if 'MOT17' in in_folder:
- video_names = [
- video_name for video_name in video_names if 'FRCNN' in video_name
- ]
- is_mot15 = True if 'MOT15' in in_folder else False
- for video_name in tqdm(video_names):
-
- video_folder = osp.join(in_folder, video_name)
- infos = list_from_file(f'{video_folder}/seqinfo.ini')
-
- assert video_name == infos[1].strip().split('=')[1]
- raw_img_folder = infos[2].strip().split('=')[1]
- raw_img_names = os.listdir(f'{video_folder}/{raw_img_folder}')
- raw_img_names = sorted(raw_img_names)
- num_raw_imgs = int(infos[4].strip().split('=')[1])
- assert num_raw_imgs == len(raw_img_names)
- reid_train_folder = osp.join(args.output, 'imgs')
- if not osp.exists(reid_train_folder):
- os.makedirs(reid_train_folder)
- gts = list_from_file(f'{video_folder}/gt/gt.txt')
- last_frame_id = -1
- for gt in gts:
- gt = gt.strip().split(',')
- frame_id, ins_id = map(int, gt[:2])
- ltwh = list(map(float, gt[2:6]))
- if is_mot15:
- class_id = 1
- visibility = 1.
- else:
- class_id = int(gt[7])
- visibility = float(gt[8])
- if class_id in USELESS:
- continue
- elif class_id in IGNORES:
- continue
- elif visibility < args.vis_threshold:
- continue
- reid_img_folder = osp.join(reid_train_folder,
- f'{video_name}_{ins_id:06d}')
- if not osp.exists(reid_img_folder):
- os.makedirs(reid_img_folder)
- idx = len(os.listdir(reid_img_folder))
- reid_img_name = f'{idx:06d}.jpg'
- if frame_id != last_frame_id:
- raw_img_name = raw_img_names[frame_id - 1]
- raw_img = mmcv.imread(
- f'{video_folder}/{raw_img_folder}/{raw_img_name}')
- last_frame_id = frame_id
- xyxy = np.asarray(
- [ltwh[0], ltwh[1], ltwh[0] + ltwh[2], ltwh[1] + ltwh[3]])
- reid_img = mmcv.imcrop(raw_img, xyxy)
- mmcv.imwrite(reid_img, f'{reid_img_folder}/{reid_img_name}')
- reid_meta_folder = osp.join(args.output, 'meta')
- if not osp.exists(reid_meta_folder):
- os.makedirs(reid_meta_folder)
- reid_train_list = []
- reid_val_list = []
- reid_img_folder_names = sorted(os.listdir(reid_train_folder))
- num_ids = len(reid_img_folder_names)
- num_train_ids = int(num_ids * (1 - args.val_split))
- train_label, val_label = 0, 0
- random.seed(0)
- for reid_img_folder_name in reid_img_folder_names[:num_train_ids]:
- reid_img_names = os.listdir(
- f'{reid_train_folder}/{reid_img_folder_name}')
-
- if (len(reid_img_names) < args.min_per_person):
- continue
-
- if (len(reid_img_names) > args.max_per_person):
- reid_img_names = random.sample(reid_img_names, args.max_per_person)
-
- for reid_img_name in reid_img_names:
- reid_train_list.append(
- f'{reid_img_folder_name}/{reid_img_name} {train_label}\n')
- train_label += 1
- reid_entire_dataset_list = reid_train_list.copy()
- for reid_img_folder_name in reid_img_folder_names[num_train_ids:]:
- reid_img_names = os.listdir(
- f'{reid_train_folder}/{reid_img_folder_name}')
-
- if (len(reid_img_names) < args.min_per_person):
- continue
-
- if (len(reid_img_names) > args.max_per_person):
- reid_img_names = random.sample(reid_img_names, args.max_per_person)
- for reid_img_name in reid_img_names:
-
- reid_val_list.append(
- f'{reid_img_folder_name}/{reid_img_name} {val_label}\n')
- reid_entire_dataset_list.append(
- f'{reid_img_folder_name}/{reid_img_name} '
- f'{train_label + val_label}\n')
- val_label += 1
- with open(
- osp.join(reid_meta_folder,
- f'train_{int(100 * (1 - args.val_split))}.txt'),
- 'w') as f:
- f.writelines(reid_train_list)
- with open(
- osp.join(reid_meta_folder, f'val_{int(100 * args.val_split)}.txt'),
- 'w') as f:
- f.writelines(reid_val_list)
- with open(osp.join(reid_meta_folder, 'train.txt'), 'w') as f:
- f.writelines(reid_entire_dataset_list)
- if __name__ == '__main__':
- main()
|