snoozey-mf-bnui/pixel-curator

Local-first CLI for turning raw photo/video archives into curated, scored, exportable datasets. No GUI, no cloud — every byte stays on your machine.

Python

7

2 commits

updated Oct 18, 2026

See the code

See what people are saying

SourceMessageScoreDate

From 1,000s of raw images to a training-ready dataset — pixel-curator (similarity training curation tool) - Dreambooth / LoRA (r/computervision)

pixel-curator — curation tooling for similarity training (identity, subject, and style models) Repo: https://github.com/snoozey-mf-bnui/pixel-curator What it is pixel-curator is a local-first CLI that takes a raw folder of images (or video) and produces a curated, scored, captioned dataset ready to…

1

Oct 13, 2026

From 1,000s of raw images to a training-ready dataset — pixel-curator (similarity training curation tool) (r/StableDiffusion)

pixel-curator — curation tooling for similarity training (identity, subject, and style models) Repo: https://github.com/snoozey-mf-bnui/pixel-curator What it is pixel-curator is a local-first CLI that takes a raw folder of images (or video) and produces a curated, scored, captioned dataset ready to…

18

Oct 13, 2026

Open-sourced my image-dataset prep tool — quality scoring, dedupe, leak-safe splits, Kohya export (pure-Python, MIT) (r/computervision)

**# I ACCIDENTALLY PUSHED THE WRONG FOLDER TO GITHUB, MY APOLOGIES - IT HAS BEEN FIXED WITH THE CORRECT FILES - Oct 12th 2026 -9:04am** I got tired of rewriting the same dataset-prep scripts before every LoRA/Dreambooth run — resize, dedupe, toss the blurry ones, caption, split — so I cleaned mine…

0

Oct 12, 2026

Open-sourced my image-dataset prep tool — quality scoring, dedupe, leak-safe splits, Kohya export (pure-Python, MIT) (r/StableDiffusion)

**# I ACCIDENTALLY PUSHED THE WRONG FOLDER TO GITHUB, MY APOLOGIES - IT HAS BEEN FIXED WITH THE CORRECT FILES - Oct 12th 2026 -9:04am** I got tired of rewriting the same dataset-prep scripts before every LoRA/Dreambooth run — resize, dedupe, toss the blurry ones, caption, split — so I cleaned mine…

9

Oct 12, 2026

README

pixel-curator

Local-first CLI for turning raw photo/video archives into curated, scored, exportable datasets. Strictly terminal-based: no GUI, no accounts, no cloud — every byte stays on your machine.

It was built to prepare LoRA training datasets, but the curation core is content-agnostic: extract frames, score quality, dedupe, caption, cluster by visual similarity, filter with natural language, review in a browser, and export the result in whatever shape you need — a flat manifest for a spreadsheet, a symlinked "best 10%" folder, or a training-ready Kohya/DreamBooth package.

What it does

StageCommandWhat happens
Set upinit, doctorScaffold a project file, verify dependencies (ffmpeg, models, backends)
Ingestextract, photos, smart-extractFrame extraction from video (HDR-aware, adaptive FPS, segmented + resumable) and photo import (JPEG/PNG/WebP/HEIC)
FilterprefilterFast multiprocessed pass to drop technically unusable frames
ScorecurateOptical quality scoring, dedup (perceptual hash), status assignment
Clustercluster, vizCLIP embeddings cached in the manifest, k-means clustering, embedding maps
Captioncaption, florenceWD14 tagger (auto-downloads), Florence-2 natural-language captions
Semantic filterfilterKeep/drop frames matching a text query ("beach photos", "images with watermarks")
Reviewreview export / review importStatic HTML report + spreadsheet keep/reject round-trip
Exportexport manifest, export select, packageFlat CSV/JSONL/Parquet manifest; top-N%/threshold/balanced selections (copy or symlink); Kohya LoRA and DreamBooth instance packages
Train & evaltrain, eval, likeness, pick-epochOptional LoRA training and identity-likeness evaluation
Operatestats, health, backup, restore, selftestManifest stats, pipeline health, safety nets, smoke tests

Everything is dry-run by default where mutations are possible, and every long stage is resumable through a SQLite manifest that tracks sources, frames, scores, captions, embeddings, clusters, dataset versions, and full lineage.

Install

Requires Python 3.10+ and ffmpeg (for video extraction).

git clone https://github.com/snoozey-mf-bnui/pixel-curator.git
cd pixel-curator
pip install -e .            # core: stdlib + Pillow + numpy

Optional extras, installed only if you need them:

pip install -e '.[caption]'   # WD14 tagging (onnxruntime, huggingface-hub)
pip install -e '.[cluster]'   # CLIP embeddings / clustering / text filter (torch, open-clip)
pip install -e '.[vlm]'       # Florence-2 captions (transformers)
pip install -e '.[parquet]'   # parquet manifest export (pandas, pyarrow)
pip install -e '.[all]'       # everything

Run either as an installed command or as a module:

pixel-curator --help
python -m pixel_curator --help

Quickstart

# 1. scaffold a project file and check your machine
pixel-curator init
pixel-curator -p myproject.toml doctor

# 2. ingest: video frames and/or photos
pixel-curator -p myproject.toml extract
pixel-curator -p myproject.toml photos

# 3. cull and score
pixel-curator -p myproject.toml prefilter
pixel-curator -p myproject.toml curate

# 4. (optional) captions + CLIP clustering
pixel-curator -p myproject.toml caption
pixel-curator -p myproject.toml cluster

# 5. look at what survived
pixel-curator -p myproject.toml stats
pixel-curator -p myproject.toml review export --out review_round_1
open review_round_1/index.html

Getting selections out (framework-agnostic)

Flat manifest — every frame, every signal, one row each. Open in any spreadsheet or dataframe tool:

pixel-curator -p myproject.toml export manifest --out manifest.csv
pixel-curator -p myproject.toml export manifest --out manifest.jsonl --format jsonl
pixel-curator -p myproject.toml export manifest --out manifest.parquet --format parquet

Selection export — materialize a slice into a folder. Symlink mode culls an 80 GB library without copying a byte:

# best 10% by unified score, as symlinks (zero-copy)
pixel-curator -p myproject.toml export select --out best10 --top-pct 10

# everything at or above score 0.8, real copies, with caption sidecars
pixel-curator -p myproject.toml export select --out heroes --min-score 0.8 --mode copy

# 500 frames spread evenly across CLIP clusters (run 'cluster' first)
pixel-curator -p myproject.toml export select --out balanced500 --balanced 500

The unified score is integrity (0–1 face-aware quality) when present, otherwise the percentile rank of sharpness — so thresholds mean the same thing regardless of which scorers ran. Every selection folder includes a selection_manifest.csv index mapping outputs back to sources.

Training packages — LoRA and DreamBooth are both first-class:

# LoRA (multi-concept): concept_<target>/ folders with dataset_config.toml
pixel-curator -p myproject.toml package kohya --dataset <export_dir> --output <pkg_dir> --mode lora --apply

# DreamBooth: a ready-to-train instance/ folder (000001.jpg + 000001.txt
# captions, dataset_config.toml) matching the standard Colab notebooks
pixel-curator -p myproject.toml package kohya --dataset <export_dir> --output <pkg_dir> --mode dreambooth --apply

The DreamBooth mode exports your curated selection as a numbered instance image set with matching caption files and a Kohya-style dataset_config.toml — point any DreamBooth trainer (Colab notebook, kohya sd-scripts, ai-toolkit) at the folder and train. Captions are assembled from the manifest's tags/quality metadata; no model calls needed at packaging time.

Semantic text filtering

Uses CLIP text encoding against cached image embeddings (run cluster once first). Dry-run by default:

# keep only beach shots
pixel-curator -p myproject.toml filter --text "beach photos" --threshold 0.25

# drop anything with visible text/watermarks
pixel-curator -p myproject.toml filter --text "image with text or watermark" --invert

# commit the changes (default is a report only)
pixel-curator -p myproject.toml filter --text "beach photos" --apply

Visual review round-trip

pixel-curator -p myproject.toml review export --out review1
open review1/index.html          # thumbnail grid, score histogram, status chips
# fill the 'decision' column in review1/review_sheet.csv: keep / reject
pixel-curator -p myproject.toml review import --sheet review1/review_sheet.csv           # dry-run
pixel-curator -p myproject.toml review import --sheet review1/review_sheet.csv --apply   # commit

reject sets a frame's status to quarantined (recoverable), keep sets kept. The HTML references your original files via file:// URLs — nothing is copied, so it works on very large libraries.

Models

Core scoring needs no models. Optional capabilities download or locate their own:

FeatureModelSetup
WD14 captionsSmilingWolf/wd-swinv2-tagger-v3 (~450 MB)auto-downloads from HuggingFace on first run
CLIP clustering / text filterViT-B-32 (open_clip, laion2b)auto-downloads on first run
Identity scoringInsightFace buffalo_l (+ optional inswapper_128.onnx)auto-downloads via the insightface package
Florence-2 captionsmicrosoft/Florence-2-base or local fine-tunesplace fine-tunes in pixel_curator/models/vlm/florence2/
Face restorationGFPGANv1.4.pthplace in pixel_curator/models/gfpgan/
UpscalingRealESRGAN_x4plus.pthplace in pixel_curator/models/realesrgan/

Model weights are gitignored — the repo never carries them.

Compute providers (CUDA / CoreML / CPU)

Everything auto-detects: auto picks CUDA → MPS/CoreML → CPU depending on the machine, so the same repo runs on an NVIDIA/Linux box, a Colab A100, or Apple Silicon unchanged. On CUDA, TF32 and bf16/fp16 autocast are enabled automatically.

To pin a dedicated provider, set it once in your project file:

[runtime]
device = "cuda"        # torch:      auto | cuda | mps | cpu
provider = "coreml"    # onnxruntime: auto | cuda | coreml | cpu
precision = "auto"     # auto | float32 | float16 | bfloat16
allow_tf32 = true

device drives torch workloads (CLIP, Florence-2); provider drives ONNX workloads (WD14 tagging, InsightFace likeness, orientation, quality signals). An unavailable choice degrades to CPU with a note — check what was selected with:

pixel-curator -p myproject.toml doctor    # shows device, dtype, providers

Project files

pixel-curator init writes a starter TOML (JSON on Python 3.10). A minimal project:

name = "my-archive"
output_dir = "./outputs"
video_dirs = ["~/Videos/shoots"]
photo_dirs = ["~/Pictures/library"]

[extract]
min_frames_per_video = 4

[curate]
# scoring/filter thresholds...

[cluster]
k = 0            # 0 = auto
batch_size = 32

Every command takes -p/--project; most also accept --json for scripting.

Tests

pixel-curator selftest            # 11 smoke checks: schema, export, review, logging

Design guarantees

  • Source media is never modified — extraction, scoring, and export only read originals; selection exports write to a new folder.
  • Resumable — the SQLite manifest tracks what's done; re-running a stage picks up where it stopped.
  • Graceful degradation — every optional model/backend falls back with a clear warning instead of crashing.
  • Dry-run first — status-changing commands report what they would do unless you pass --apply.

License

MIT — see LICENSE.

snoozey-mf-bnui/pixel-curator

Local-first CLI for turning raw photo/video archives into curated, scored, exportable datasets. No GUI, no cloud — every byte stays on your machine.

Python

7

2 commits

updated Oct 18, 2026

See the code

See what people are saying

SourceMessageScoreDate

From 1,000s of raw images to a training-ready dataset — pixel-curator (similarity training curation tool) - Dreambooth / LoRA (r/computervision)

pixel-curator — curation tooling for similarity training (identity, subject, and style models) Repo: https://github.com/snoozey-mf-bnui/pixel-curator What it is pixel-curator is a local-first CLI that takes a raw folder of images (or video) and produces a curated, scored, captioned dataset ready to…

1

Oct 13, 2026

From 1,000s of raw images to a training-ready dataset — pixel-curator (similarity training curation tool) (r/StableDiffusion)

pixel-curator — curation tooling for similarity training (identity, subject, and style models) Repo: https://github.com/snoozey-mf-bnui/pixel-curator What it is pixel-curator is a local-first CLI that takes a raw folder of images (or video) and produces a curated, scored, captioned dataset ready to…

18

Oct 13, 2026

Open-sourced my image-dataset prep tool — quality scoring, dedupe, leak-safe splits, Kohya export (pure-Python, MIT) (r/computervision)

**# I ACCIDENTALLY PUSHED THE WRONG FOLDER TO GITHUB, MY APOLOGIES - IT HAS BEEN FIXED WITH THE CORRECT FILES - Oct 12th 2026 -9:04am** I got tired of rewriting the same dataset-prep scripts before every LoRA/Dreambooth run — resize, dedupe, toss the blurry ones, caption, split — so I cleaned mine…

0

Oct 12, 2026

Open-sourced my image-dataset prep tool — quality scoring, dedupe, leak-safe splits, Kohya export (pure-Python, MIT) (r/StableDiffusion)

**# I ACCIDENTALLY PUSHED THE WRONG FOLDER TO GITHUB, MY APOLOGIES - IT HAS BEEN FIXED WITH THE CORRECT FILES - Oct 12th 2026 -9:04am** I got tired of rewriting the same dataset-prep scripts before every LoRA/Dreambooth run — resize, dedupe, toss the blurry ones, caption, split — so I cleaned mine…

9

Oct 12, 2026

README

pixel-curator

Local-first CLI for turning raw photo/video archives into curated, scored, exportable datasets. Strictly terminal-based: no GUI, no accounts, no cloud — every byte stays on your machine.

It was built to prepare LoRA training datasets, but the curation core is content-agnostic: extract frames, score quality, dedupe, caption, cluster by visual similarity, filter with natural language, review in a browser, and export the result in whatever shape you need — a flat manifest for a spreadsheet, a symlinked "best 10%" folder, or a training-ready Kohya/DreamBooth package.

What it does

StageCommandWhat happens
Set upinit, doctorScaffold a project file, verify dependencies (ffmpeg, models, backends)
Ingestextract, photos, smart-extractFrame extraction from video (HDR-aware, adaptive FPS, segmented + resumable) and photo import (JPEG/PNG/WebP/HEIC)
FilterprefilterFast multiprocessed pass to drop technically unusable frames
ScorecurateOptical quality scoring, dedup (perceptual hash), status assignment
Clustercluster, vizCLIP embeddings cached in the manifest, k-means clustering, embedding maps
Captioncaption, florenceWD14 tagger (auto-downloads), Florence-2 natural-language captions
Semantic filterfilterKeep/drop frames matching a text query ("beach photos", "images with watermarks")
Reviewreview export / review importStatic HTML report + spreadsheet keep/reject round-trip
Exportexport manifest, export select, packageFlat CSV/JSONL/Parquet manifest; top-N%/threshold/balanced selections (copy or symlink); Kohya LoRA and DreamBooth instance packages
Train & evaltrain, eval, likeness, pick-epochOptional LoRA training and identity-likeness evaluation
Operatestats, health, backup, restore, selftestManifest stats, pipeline health, safety nets, smoke tests

Everything is dry-run by default where mutations are possible, and every long stage is resumable through a SQLite manifest that tracks sources, frames, scores, captions, embeddings, clusters, dataset versions, and full lineage.

Install

Requires Python 3.10+ and ffmpeg (for video extraction).

git clone https://github.com/snoozey-mf-bnui/pixel-curator.git
cd pixel-curator
pip install -e .            # core: stdlib + Pillow + numpy

Optional extras, installed only if you need them:

pip install -e '.[caption]'   # WD14 tagging (onnxruntime, huggingface-hub)
pip install -e '.[cluster]'   # CLIP embeddings / clustering / text filter (torch, open-clip)
pip install -e '.[vlm]'       # Florence-2 captions (transformers)
pip install -e '.[parquet]'   # parquet manifest export (pandas, pyarrow)
pip install -e '.[all]'       # everything

Run either as an installed command or as a module:

pixel-curator --help
python -m pixel_curator --help

Quickstart

# 1. scaffold a project file and check your machine
pixel-curator init
pixel-curator -p myproject.toml doctor

# 2. ingest: video frames and/or photos
pixel-curator -p myproject.toml extract
pixel-curator -p myproject.toml photos

# 3. cull and score
pixel-curator -p myproject.toml prefilter
pixel-curator -p myproject.toml curate

# 4. (optional) captions + CLIP clustering
pixel-curator -p myproject.toml caption
pixel-curator -p myproject.toml cluster

# 5. look at what survived
pixel-curator -p myproject.toml stats
pixel-curator -p myproject.toml review export --out review_round_1
open review_round_1/index.html

Getting selections out (framework-agnostic)

Flat manifest — every frame, every signal, one row each. Open in any spreadsheet or dataframe tool:

pixel-curator -p myproject.toml export manifest --out manifest.csv
pixel-curator -p myproject.toml export manifest --out manifest.jsonl --format jsonl
pixel-curator -p myproject.toml export manifest --out manifest.parquet --format parquet

Selection export — materialize a slice into a folder. Symlink mode culls an 80 GB library without copying a byte:

# best 10% by unified score, as symlinks (zero-copy)
pixel-curator -p myproject.toml export select --out best10 --top-pct 10

# everything at or above score 0.8, real copies, with caption sidecars
pixel-curator -p myproject.toml export select --out heroes --min-score 0.8 --mode copy

# 500 frames spread evenly across CLIP clusters (run 'cluster' first)
pixel-curator -p myproject.toml export select --out balanced500 --balanced 500

The unified score is integrity (0–1 face-aware quality) when present, otherwise the percentile rank of sharpness — so thresholds mean the same thing regardless of which scorers ran. Every selection folder includes a selection_manifest.csv index mapping outputs back to sources.

Training packages — LoRA and DreamBooth are both first-class:

# LoRA (multi-concept): concept_<target>/ folders with dataset_config.toml
pixel-curator -p myproject.toml package kohya --dataset <export_dir> --output <pkg_dir> --mode lora --apply

# DreamBooth: a ready-to-train instance/ folder (000001.jpg + 000001.txt
# captions, dataset_config.toml) matching the standard Colab notebooks
pixel-curator -p myproject.toml package kohya --dataset <export_dir> --output <pkg_dir> --mode dreambooth --apply

The DreamBooth mode exports your curated selection as a numbered instance image set with matching caption files and a Kohya-style dataset_config.toml — point any DreamBooth trainer (Colab notebook, kohya sd-scripts, ai-toolkit) at the folder and train. Captions are assembled from the manifest's tags/quality metadata; no model calls needed at packaging time.

Semantic text filtering

Uses CLIP text encoding against cached image embeddings (run cluster once first). Dry-run by default:

# keep only beach shots
pixel-curator -p myproject.toml filter --text "beach photos" --threshold 0.25

# drop anything with visible text/watermarks
pixel-curator -p myproject.toml filter --text "image with text or watermark" --invert

# commit the changes (default is a report only)
pixel-curator -p myproject.toml filter --text "beach photos" --apply

Visual review round-trip

pixel-curator -p myproject.toml review export --out review1
open review1/index.html          # thumbnail grid, score histogram, status chips
# fill the 'decision' column in review1/review_sheet.csv: keep / reject
pixel-curator -p myproject.toml review import --sheet review1/review_sheet.csv           # dry-run
pixel-curator -p myproject.toml review import --sheet review1/review_sheet.csv --apply   # commit

reject sets a frame's status to quarantined (recoverable), keep sets kept. The HTML references your original files via file:// URLs — nothing is copied, so it works on very large libraries.

Models

Core scoring needs no models. Optional capabilities download or locate their own:

FeatureModelSetup
WD14 captionsSmilingWolf/wd-swinv2-tagger-v3 (~450 MB)auto-downloads from HuggingFace on first run
CLIP clustering / text filterViT-B-32 (open_clip, laion2b)auto-downloads on first run
Identity scoringInsightFace buffalo_l (+ optional inswapper_128.onnx)auto-downloads via the insightface package
Florence-2 captionsmicrosoft/Florence-2-base or local fine-tunesplace fine-tunes in pixel_curator/models/vlm/florence2/
Face restorationGFPGANv1.4.pthplace in pixel_curator/models/gfpgan/
UpscalingRealESRGAN_x4plus.pthplace in pixel_curator/models/realesrgan/

Model weights are gitignored — the repo never carries them.

Compute providers (CUDA / CoreML / CPU)

Everything auto-detects: auto picks CUDA → MPS/CoreML → CPU depending on the machine, so the same repo runs on an NVIDIA/Linux box, a Colab A100, or Apple Silicon unchanged. On CUDA, TF32 and bf16/fp16 autocast are enabled automatically.

To pin a dedicated provider, set it once in your project file:

[runtime]
device = "cuda"        # torch:      auto | cuda | mps | cpu
provider = "coreml"    # onnxruntime: auto | cuda | coreml | cpu
precision = "auto"     # auto | float32 | float16 | bfloat16
allow_tf32 = true

device drives torch workloads (CLIP, Florence-2); provider drives ONNX workloads (WD14 tagging, InsightFace likeness, orientation, quality signals). An unavailable choice degrades to CPU with a note — check what was selected with:

pixel-curator -p myproject.toml doctor    # shows device, dtype, providers

Project files

pixel-curator init writes a starter TOML (JSON on Python 3.10). A minimal project:

name = "my-archive"
output_dir = "./outputs"
video_dirs = ["~/Videos/shoots"]
photo_dirs = ["~/Pictures/library"]

[extract]
min_frames_per_video = 4

[curate]
# scoring/filter thresholds...

[cluster]
k = 0            # 0 = auto
batch_size = 32

Every command takes -p/--project; most also accept --json for scripting.

Tests

pixel-curator selftest            # 11 smoke checks: schema, export, review, logging

Design guarantees

  • Source media is never modified — extraction, scoring, and export only read originals; selection exports write to a new folder.
  • Resumable — the SQLite manifest tracks what's done; re-running a stage picks up where it stopped.
  • Graceful degradation — every optional model/backend falls back with a clear warning instead of crashing.
  • Dry-run first — status-changing commands report what they would do unless you pass --apply.

License

MIT — see LICENSE.