Download src/tool/make_nyu_calibration.py from AXERA-TECH/DepthART: direct link, hf CLI and curl.
- Browser
- Download file 4.25 kB
-
https://huggingface.co/AXERA-TECH/DepthART/resolve/main/src/tool/make_nyu_calibration.py
- Command line
-
hf download hf://AXERA-TECH/DepthART/src/tool/make_nyu_calibration.py
-
curl -L -o make_nyu_calibration.py https://huggingface.co/AXERA-TECH/DepthART/resolve/main/src/tool/make_nyu_calibration.py
4.25 kB
| #!/usr/bin/env python3 | |
| # -*- coding: utf-8 -*- | |
| """ | |
| 从 NYU 训练集 795 张中按场景均匀抽取量化校准图片。 | |
| 抽样规则: | |
| - 按场景类型(scene 去掉 _0001 后缀,如 kitchen、bedroom)分组; | |
| - 每个场景至少 1 张,其余名额按场景图片数比例分配(最大余数法); | |
| - 场景内按等距索引选取,结果确定可复现。 | |
| 输出: | |
| <out-dir>/images/*.png 校准图片 | |
| <out-dir>/selection.json 每张图的来源 mat_index / scene / 源文件 | |
| <out-dir>/<name>.tar 给 pulsar2 的校准包,内部为 <name>/xxx.png | |
| 用法: | |
| ../../venv/bin/python src/tool/make_nyu_calibration.py \ | |
| --source-dir datasets/nyu_train795 --count 48 \ | |
| --out-dir datasets/nyu_calibration_48 | |
| """ | |
| import argparse | |
| import json | |
| import shutil | |
| import subprocess | |
| from collections import defaultdict | |
| from pathlib import Path | |
| import cv2 | |
| import numpy as np | |
| def scene_type(scene): | |
| return scene.rsplit('_', 1)[0] | |
| def allocate(groups, count): | |
| """最大余数法分配名额,每个场景至少 1 张。""" | |
| total = sum(len(v) for v in groups.values()) | |
| if count < len(groups): | |
| raise ValueError(f'抽取数量 {count} 少于场景数 {len(groups)},无法保证每场景 1 张') | |
| quota = {k: 1 for k in groups} | |
| left = count - len(groups) | |
| exact = {k: left * len(v) / total for k, v in groups.items()} | |
| for k, v in exact.items(): | |
| quota[k] += int(np.floor(v)) | |
| remain = count - sum(quota.values()) | |
| order = sorted(exact, key=lambda k: exact[k] - np.floor(exact[k]), reverse=True) | |
| for k in order[:remain]: | |
| quota[k] += 1 | |
| return quota | |
| def main(): | |
| parser = argparse.ArgumentParser(description='按场景均匀抽取 NYU 校准集') | |
| parser.add_argument('--source-dir', required=True, help='export_nyu_train795.py 的输出目录') | |
| parser.add_argument('--count', type=int, default=48, help='抽取张数,默认 48') | |
| parser.add_argument('--out-dir', required=True, help='校准集输出目录') | |
| parser.add_argument('--name', help='tar 包内目录名,默认取 out-dir 名') | |
| parser.add_argument('--ext', choices=('png', 'jpg'), default='png', | |
| help='校准图片格式,默认 png;pulsar2 读取异常时可改 jpg') | |
| args = parser.parse_args() | |
| source = Path(args.source_dir) | |
| split = json.load(open(source / 'split.json')) | |
| groups = defaultdict(list) | |
| for record in split: | |
| groups[scene_type(record['scene'])].append(record) | |
| quota = allocate(groups, args.count) | |
| selected = [] | |
| for scene, records in sorted(groups.items()): | |
| records = sorted(records, key=lambda r: r['file']) | |
| idx = np.linspace(0, len(records) - 1, quota[scene]).round().astype(int) | |
| selected.extend(records[i] for i in sorted(set(idx.tolist()))) | |
| if len(selected) != args.count: | |
| raise RuntimeError(f'实际选出 {len(selected)} 张,与目标 {args.count} 不符') | |
| out_dir = Path(args.out_dir) | |
| image_dir = out_dir / 'images' | |
| image_dir.mkdir(parents=True, exist_ok=True) | |
| for record in selected: | |
| src = source / 'images' / record['file'] | |
| if args.ext == 'png': | |
| dst = image_dir / record['file'] | |
| shutil.copy2(src, dst) | |
| else: | |
| dst = image_dir / (Path(record['file']).stem + '.jpg') | |
| image = cv2.imread(str(src), cv2.IMREAD_COLOR) | |
| if image is None: | |
| raise RuntimeError(f'读取失败: {src}') | |
| cv2.imwrite(str(dst), image, [cv2.IMWRITE_JPEG_QUALITY, 95]) | |
| with open(out_dir / 'selection.json', 'w') as fp: | |
| json.dump(selected, fp, indent=2) | |
| name = args.name or out_dir.name | |
| tar_path = out_dir / f'{name}.tar' | |
| subprocess.run( | |
| ['tar', '-cf', str(tar_path), '--transform', f's,^,{name}/,', '-C', str(image_dir)] | |
| + sorted(p.name for p in image_dir.iterdir()), | |
| check=True) | |
| print(f'已抽取 {len(selected)} 张,覆盖 {len(groups)} 个场景类型') | |
| for scene in sorted(groups): | |
| print(f' {scene:<16} {quota[scene]:>3} 张 / 共 {len(groups[scene])}') | |
| print(f'校准包: {tar_path}') | |
| if __name__ == '__main__': | |
| main() | |