"""Generate train/val/test list files for list-based change-detection loaders.""" from __future__ import annotations import argparse import os import sys from pathlib import Path ROOT = Path(__file__).resolve().parents[1] if str(ROOT) not in sys.path: sys.path.insert(0, str(ROOT)) IMG_EXTS = {".png", ".jpg", ".jpeg", ".tif", ".tiff", ".bmp"} def generate_list_files( data_root: str, splits: list[str] | None = None, img_subdir: str = "A", overwrite: bool = False, ) -> dict[str, int]: if splits is None: splits = ["train", "val", "test"] root = Path(data_root) list_dir = root / "list" list_dir.mkdir(parents=True, exist_ok=True) results: dict[str, int] = {} for split in splits: list_file = list_dir / f"{split}.txt" if list_file.exists() and not overwrite: count = sum(1 for _ in list_file.open("r", encoding="utf-8")) print(f" [SKIP] {list_file} already exists ({count} entries)") results[split] = count continue img_dir = None for candidate in [img_subdir, "A", "T1", "t1", "img", "images", "image"]: candidate_path = root / split / candidate if candidate_path.is_dir(): img_dir = candidate_path break if img_dir is None: print(f" [WARN] No image directory found under {root / split} - skipping {split}") results[split] = 0 continue filenames = sorted( p.name for p in img_dir.iterdir() if p.is_file() and p.suffix.lower() in IMG_EXTS ) if not filenames: print(f" [WARN] No image files found in {img_dir}") results[split] = 0 continue list_file.write_text("\n".join(filenames) + "\n", encoding="utf-8") print(f" [OK] {list_file}: {len(filenames)} entries") results[split] = len(filenames) return results def generate_for_dataset(dataset_name: str, overwrite: bool = False) -> None: from utils.config_loader import load_dataset_config cfg = load_dataset_config(dataset_name) data_root = cfg["data_root"] if not os.path.isdir(data_root): print(f"[SKIP] Dataset root does not exist: {data_root}") return img_subdir = cfg.get("image_a_folder", "A") splits = list((cfg.get("splits") or {"train": "train", "val": "val", "test": "test"}).keys()) print(f"[LIST_GEN] Generating list files for {dataset_name} at {data_root}") results = generate_list_files(data_root, splits=splits, img_subdir=img_subdir, overwrite=overwrite) print(f"[LIST_GEN] Done: {results}") if __name__ == "__main__": parser = argparse.ArgumentParser() parser.add_argument("--dataset", type=str, default=None) parser.add_argument("--all", action="store_true") parser.add_argument("--overwrite", action="store_true") args = parser.parse_args() from utils.config_loader import list_available_datasets datasets = list_available_datasets() if args.all else ([args.dataset] if args.dataset else []) for ds in datasets: generate_for_dataset(ds, overwrite=args.overwrite)