A Windows desktop DDD Image Organizer that uses a local vision LLM to sort a folder of loose images into categorized subfolders, based on what is depicted in each image.
Local-first. No API keys, no uploading to the cloud. Images and the LLM stay on this machine (Ollama or LM Studio).
Pick a folder full of images → a vision model looks at each one → you review the proposed folder assignments in a preview grid → apply with one click (move or copy). A journal makes every run undoable.
- Python 3.10+
- PyQt6, openai, pillow (
pip install -r requirements.txt) - A vision-capable model running locally, one of:
- Ollama —
ollama serverunning, with a vision model pulled (e.g.ollama pull llama3.2-vision). - LM Studio — server mode enabled (Settings → Developer → Start Server), with a vision model loaded.
- Ollama —
Recommended model: minicpm-v-4.6 (small, fast, accurate, non-thinking — no reasoning-loop hangs).
python main.py- Pick the backend (Ollama / LM Studio) and refresh the model list — or type a model name directly.
- Browse to the folder with the loose images, tick Include subfolders if needed, click Scan.
- Optionally set an organizing instruction (e.g. "group by decade", "portraits by person") in Settings & Diagnostics → Prompt.
- Set a folder structure — the app ships with a built-in Default template (
humans,animals,plants,places/…,objects,events,misc). You can use it as-is, load a saved one, or define your own. When a structure is active, the model routes into EXACTLY those folders; leave it empty for free-form names. - Click Classify images. Each image is downscaled to a JPEG and sent to the local model; the model returns a folder name and a one-line reason.
- Uncheck any assignment you disagree with, then click Apply (Move) or Apply (Copy).
- Preview before applying — nothing moves until you approve the plan.
- Journal — every run is written to
_image_organizer_journal.json; Undo last run reverses it. - Copy mode keeps originals untouched.
- Duplicate target names get a
(1),(2)suffix instead of being overwritten.
All options live in config.json next to the app and are editable from the Settings tab:
| Setting | What it does |
|---|---|
| Backend URLs | Ollama /v1 and LM Studio /v1 endpoints |
| Batch | how many images are sent to the model at once |
| Max image side / JPEG quality | downscale before upload (speed / accuracy trade-off) |
| Temperature | 0 = pick the same folder every time |
| Mode | move or copy |
| Folder structure | user-defined tree (built-in Default template + your saved templates) |
| Prompt | the organizing instruction handed to the model |
- Refresh models fails silently? — check the URL in Settings & Diagnostics (Ollama=
http://localhost:11434/v1, LM Studio=http://localhost:1234/v1) and make sure the server is running. The exact error also appears in the Log tab and status bar. - Not sure what settings to use? — Settings & Diagnostics → Run system check inspects your hardware and proposes fitting settings (e.g. batch size 1 and lower resolution for a weak PC). Click Apply suggested settings, then Save settings.
Logs stream live in the Log tab and are also written to image_organizer.log next to main.py (rotating, 3 × 1 MB backups).
main.py entry point (PyQt6)
core/
config.py persisted settings (config.json)
backends.py OpenAI-compatible vision client for Ollama / LM Studio
organizer.py scan, classify (batched), apply, journal, undo
diagnostic.py hardware / backend check + suggestions
ui/
main_window.py the app UI
images/ and image_samples_OG/ both ship a matching set of 10 sample images — humans, animals, plants, places, objects, and a couple of edge cases. Handy for reproducing the workflow and smoke-testing a new vision model.