Handy scripts for cleaning, resizing, labeling and curating image datasets.
Works with both photos and anime — stylistic things (white background,
dark theme, bokeh, grass/bark texture) are not treated as defects, only real
breakage is flagged. Everything runs locally.
The repo ships a ready-made skill for the pi agent
(Agent Skills format). The agent reads the skill
description, picks the right script and runs it for you.
Defect detector (v2): blur, noise, over/underexposure, JPEG artifacts, screenshots, color cast, empty. First found cause wins. Also classify_media() — photo vs illustration, used to pick per-type thresholds. Self-test on synthetic images
PIL, numpy
resize/
preprocess_dataset.py
Resize + center-crop every image into buckets [min..max] with step alignment, sequential naming + paired .txt captions
PIL, tqdm
resize/
img_sizes.py
Recursive report of image sizes (TSV + top sizes) — pick buckets before resizing
PIL
resize/
diverse_images.py
Per resolution bucket: N random → M most diverse by CLIP → resize + captions
torch, transformers
search/
similar_images.py
Top N% of images most similar to a reference (CLIP embeddings), copy + captions
torch, transformers
caption/
caption.py
Batch captioning with Moondream 2 (skips already-labeled, checks broken)
transformers, torch
caption/
wd14_tagger.py
danbooru tags WD14 (SmilingWolf/wd-*-tagger-v3) for anime: vit/swinv2/convnext
torch, timm, pandas
civitai/
download_feed.py
Download civitai feed (best of the month) with prompts
requests
civitai/
download_collection.py
Download civitai collection with prompts (JPEG q97)
1# report only2python quality/scan.py /path/to/images
34# sort into cause folders: blur/, noise/, overexposed/, underexposed/,5# jpeg_artifacts/, screenshot/, color_cast/, not_photo/, good/6python quality/scan.py --sort /path/to/images --copy -j 1678# collect ONLY bad cases (skip good), 16 parallel workers, first 10k images9python quality/scan.py --sort /path/to/images --copy -j 16 --no-good --limit 100001011# sanity check on synthetic images12python quality/scan.py --self-test
Analysis runs on a fixed long edge of 1024 (both up and down) so thresholds
don't drift between datasets of different sizes; noise and JPEG artifacts are
measured on the original (resize smooths noise and breaks the 8×8 grid).
2. Resize into buckets (fit a model)
bash
1# what sizes are actually in the dataset?2python resize/img_sizes.py /path/to/images
34# SDXS-1B: 320–640, step 645python resize/preprocess_dataset.py --input /path/to/images --output /path/to/out \6 --min-size 320 --max-size 640 --step 6478# FLUX / ~1MP: 1024–1152, step 649python resize/preprocess_dataset.py --input /path/to/images --output /path/to/out \10 --min-size 1024 --max-size 1152 --step 64 --dry-run # preview first
1# M most diverse images per resolution bucket (balance a dataset)2python resize/diverse_images.py /path/to/images --output ./diverse --take 500 --pick 5034# top 5% most similar to a reference image5python search/similar_images.py /path/to/images --reference ref.jpg \6 --output ./top5 --percent 5