Download dataset/split_coco.py from stereoid/Orienter: direct link, hf CLI and curl.
- Browser
- Download file 6.76 kB
-
https://huggingface.co/stereoid/Orienter/resolve/main/dataset/split_coco.py
- Command line
-
hf download hf://stereoid/Orienter/dataset/split_coco.py
-
curl -L -o split_coco.py https://huggingface.co/stereoid/Orienter/resolve/main/dataset/split_coco.py
6.76 kB
| import os | |
| import json | |
| import shutil | |
| import argparse | |
| import random | |
| import pandas as pd | |
| FOLD_CNT = 10 | |
| def generate_fold(args): | |
| df = pd.DataFrame(columns=['img_id', 'fold']) | |
| json_file_path = args.ann_file | |
| assert os.path.exists(json_file_path), f'json file not found: {json_file_path}' | |
| with open(json_file_path, 'r') as f: | |
| json_data = json.load(f) | |
| # reproducable random shuffle | |
| random.seed(1) | |
| random.shuffle(json_data['images']) | |
| fold_size = len(json_data['images']) // FOLD_CNT | |
| for image in json_data['images']: | |
| df.loc[len(df), df.columns] = [image['id'], min(len(df) // fold_size, FOLD_CNT - 1)] | |
| df.to_csv(args.fold_file, index=False) | |
| def generate_fold_app(args): | |
| df = pd.DataFrame(columns=['img_id', 'fold']) | |
| json_file_path = args.ann_file | |
| assert os.path.exists(json_file_path), f'json file not found: {json_file_path}' | |
| with open(json_file_path, 'r') as f: | |
| json_data = json.load(f) | |
| apps = set() | |
| for image in json_data['images']: | |
| appid = str(image['id'])[:-3] | |
| apps.add(appid) | |
| apps = list(apps) | |
| bel_app = {} | |
| # reproducable random shuffle | |
| apps = sorted(apps) | |
| random.seed(1) | |
| random.shuffle(apps) | |
| fold_size = len(apps) // FOLD_CNT | |
| for app in apps: | |
| bel_app[app] = min(len(bel_app) // fold_size, FOLD_CNT - 1) | |
| for image in json_data['images']: | |
| appid = str(image['id'])[:-3] | |
| df.loc[len(df), df.columns] = [image['id'], bel_app[appid]] | |
| df = df.sort_values(by='fold') | |
| df.to_csv(args.fold_file, index=False) | |
| def split(args): | |
| json_file_path = args.ann_file | |
| image_path = args.img_dir if args.img_dir and os.path.exists(args.img_dir) else None | |
| fold_file = args.fold_file | |
| output_path = args.output_path | |
| assert os.path.exists(json_file_path), f'json file not found: {json_file_path}' | |
| # assert os.path.exists(image_path), f'image path not found: {image_path}' | |
| assert os.path.exists(fold_file), f'fold file not found: {fold_file}' | |
| with open(json_file_path, 'r') as f: | |
| json_data = json.load(f) | |
| df = pd.read_csv(fold_file) | |
| train_dataset = {'images': list(), 'categories': json_data['categories'], 'annotations': list()} | |
| val_dataset = {'images': list(), 'categories': json_data['categories'], 'annotations': list()} | |
| test_dataset = {'images': list(), 'categories': json_data['categories'], 'annotations': list()} | |
| train_folds = [int(fold) for fold in args.train_folds.split(',')] if args.train_folds else [] | |
| val_folds = [int(fold) for fold in args.val_folds.split(',')] if args.val_folds else [] | |
| test_folds = [int(fold) for fold in args.test_folds.split(',')] if args.test_folds else [] | |
| print(f'train folds: {train_folds}') | |
| print(f'val folds: {val_folds}') | |
| print(f'test folds: {test_folds}') | |
| train_imgid = set() | |
| val_imgid = set() | |
| test_imgid = set() | |
| for _, row in df.iterrows(): | |
| if row['fold'] in train_folds: | |
| train_imgid.add(row['img_id']) | |
| elif row['fold'] in val_folds: | |
| val_imgid.add(row['img_id']) | |
| elif row['fold'] in test_folds: | |
| test_imgid.add(row['img_id']) | |
| else: | |
| raise ValueError(f'fold not found: {row["fold"]}') | |
| for image in json_data['images']: | |
| if image['id'] in train_imgid: | |
| train_dataset['images'].append(image) | |
| elif image['id'] in val_imgid: | |
| val_dataset['images'].append(image) | |
| elif image['id'] in test_imgid: | |
| test_dataset['images'].append(image) | |
| else: | |
| raise ValueError(f'image id not found: {image["id"]}') | |
| for annotation in json_data['annotations']: | |
| if annotation['image_id'] in train_imgid: | |
| train_dataset['annotations'].append(annotation) | |
| elif annotation['image_id'] in val_imgid: | |
| val_dataset['annotations'].append(annotation) | |
| elif annotation['image_id'] in test_imgid: | |
| test_dataset['annotations'].append(annotation) | |
| else: | |
| raise ValueError(f'annotation image_id not found: {annotation["image_id"]}') | |
| print(f'train dataset: {len(train_dataset["images"])} images, {len(train_dataset["annotations"])} annotations') | |
| print(f'val dataset: {len(val_dataset["images"])} images, {len(val_dataset["annotations"])} annotations') | |
| print(f'test dataset: {len(test_dataset["images"])} images, {len(test_dataset["annotations"])} annotations') | |
| print(os.path.abspath(output_path)) | |
| train_image_path = os.path.join(output_path, 'images', 'instances_train2017') | |
| val_image_path = os.path.join(output_path, 'images', 'instances_val2017') | |
| test_image_path = os.path.join(output_path, 'images', 'instances_test2017') | |
| os.makedirs(output_path, exist_ok=True) | |
| os.makedirs(train_image_path, exist_ok=True) | |
| os.makedirs(val_image_path, exist_ok=True) | |
| os.makedirs(test_image_path, exist_ok=True) | |
| os.makedirs(os.path.join(output_path, 'annotations'), exist_ok=True) | |
| with open(os.path.join(output_path, 'annotations', 'instances_train2017.json'), 'w') as f: | |
| json.dump(train_dataset, f, indent=4) | |
| with open(os.path.join(output_path, 'annotations', 'instances_val2017.json'), 'w') as f: | |
| json.dump(val_dataset, f, indent=4) | |
| with open(os.path.join(output_path, 'annotations', 'instances_test2017.json'), 'w') as f: | |
| json.dump(test_dataset, f, indent=4) | |
| if image_path: | |
| for image in train_dataset['images']: | |
| shutil.copy(os.path.join(image_path, image['file_name']), train_image_path) | |
| for image in val_dataset['images']: | |
| shutil.copy(os.path.join(image_path, image['file_name']), val_image_path) | |
| for image in test_dataset['images']: | |
| shutil.copy(os.path.join(image_path, image['file_name']), test_image_path) | |
| def main(args): | |
| if args.gen: | |
| generate_fold_app(args) | |
| split(args) | |
| if __name__ == '__main__': | |
| parser = argparse.ArgumentParser() | |
| parser.add_argument('--ann_file', type=str, required=True) | |
| parser.add_argument('--img_dir', type=str, required=True) | |
| parser.add_argument('--output_path', type=str, default='./coco_split') | |
| parser.add_argument('--train_folds', type=str, default=None) | |
| parser.add_argument('--val_folds', type=str, default=None) | |
| parser.add_argument('--test_folds', type=str, default=None) | |
| parser.add_argument('--gen', action='store_true') | |
| parser.add_argument('--fold_file', type=str, required=True) | |
| args = parser.parse_args() | |
| main(args) | |