Add source-aware scoring and size hinting to lattice inference: introduce _hint_target_sizes_from_spacing, _top_candidates_by_size, _normalize_candidate_scores and _rerank_size_candidates_with_source_evidence in inference.py; use spacing-based hinted sizes when enumerating candidates and rerank candidates by combined base score and source-lattice evidence before selecting the best lattice. Add source_lattice_evidence_breakdown and foreground_adjacency_strength to metrics.py to compute per-candidate evidence (cell dispersion and adjacency strength). Update infer_lattice to return reranked top candidates. Update tests to cover spacing hints, size diversification, and phase/size reranking; adjust pipeline synthetic test parameters. Also update README wording and refresh/remove some readme image assets.
125 lines
4.7 KiB
Markdown
125 lines
4.7 KiB
Markdown
# Repixelizer
|
|
|
|
Repixelizer is a standalone Python CLI for images that are doing a pixel art impression instead of actually respecting the grid.
|
|
|
|
It is aimed at the annoying middle ground: sprites, emblems, and logos that look locally pixelated but fall apart the second you ask them to commit to one lattice like grown-ups.
|
|
|
|
Instead of pretending this is a resize problem, Repixelizer treats it as lattice inference plus local structure preservation: infer the implied grid, choose real output cells, and snap them back onto a coherent pixel lattice while preserving the source's local adjacency patterns.
|
|
|
|
## Examples
|
|
|
|
Repixelizer was built to rescue fake pixel art, but it can also be used to generate pixel art directly from non-pixel source art when the shapes are clean and the local structure is doing something useful.
|
|
|
|
Top row: glossy non-pixel badge art repixelized at `128x128`. Bottom row: an AI fake-pixel interpretation of the same badge cleaned up with automatic lattice inference, which landed on `122x122` for this image.
|
|
|
|

|
|
|
|
That is the two-headed pitch in one image: force non-pixel art onto a coherent grid, or take AI pixel art that only respects the grid locally and make it commit.
|
|
|
|
## Current Status
|
|
|
|
This is already a serious experimental baseline, not a toy prototype:
|
|
|
|
- CUDA-backed inference and solver paths are wired up
|
|
- round-trip corpus benchmarking is built in
|
|
- soft and crisp corruption profiles are supported
|
|
- diagnostics and baseline comparisons are written automatically
|
|
- a black-box tuning harness exists for longer offline parameter sweeps
|
|
|
|
The current pipeline is especially strong on benchmarked sprite and emblem inputs where local fake-pixel texture is meaningful but the global grid is inconsistent.
|
|
|
|
## Quickstart
|
|
|
|
```powershell
|
|
python -m venv .venv
|
|
.venv\Scripts\python -m pip install -e .[dev]
|
|
```
|
|
|
|
Run the optimizer:
|
|
|
|
```powershell
|
|
repixelize input.png --out output.png
|
|
repixelize input.png --out output.png --diagnostics-dir diagnostics --device auto
|
|
```
|
|
|
|
Run the optimizer plus baselines:
|
|
|
|
```powershell
|
|
repixelize compare input.png --out output.png --diagnostics-dir diagnostics
|
|
```
|
|
|
|
## Corpus And Benchmarks
|
|
|
|
Prepare a local Creative Commons corpus:
|
|
|
|
```powershell
|
|
repixelize prepare-corpus --corpus-dir examples/corpus
|
|
```
|
|
|
|
Run the round-trip benchmark:
|
|
|
|
```powershell
|
|
repixelize benchmark --corpus-dir examples/corpus --out-dir artifacts/benchmark
|
|
```
|
|
|
|
Useful benchmark flags:
|
|
|
|
- `--profile soft` or `--profile crisp`
|
|
- `--case <name>` repeated for a focused slice
|
|
- `--limit <n>` for the first `n` matching cases
|
|
- `--infer-size` to test automatic size inference
|
|
- `--keep-existing` if you explicitly want to preserve an old output directory
|
|
|
|
By default the benchmark clears its output directory before each run so the artifacts folder stays readable.
|
|
|
|
## Tuning
|
|
|
|
Repixelizer includes a black-box tuning loop for longer offline searches over solver weights:
|
|
|
|
```powershell
|
|
repixelize tune --corpus-dir examples/corpus --out-dir artifacts/tuning --profile soft --limit 8
|
|
```
|
|
|
|
This is intentionally a search-based tuner, not gradient descent. The objective depends on discrete argmins, thresholding, and benchmark comparisons, so it is better treated as a repeatable black-box optimization problem.
|
|
|
|
## Repository Hygiene
|
|
|
|
This repo is set up to be safe for local experimentation:
|
|
|
|
- generated outputs under `artifacts/` are ignored
|
|
- local corpus payloads under `examples/corpus/originals/` are ignored
|
|
- archived raw sprite sheets under `examples/corpus/source-sheets/` are ignored
|
|
- generated corpus metadata files are ignored
|
|
|
|
That keeps benchmark assets, attribution exports, and tuning runs from polluting upstream history while still keeping the code, docs, and corpus layout tracked.
|
|
|
|
## Repo Layout
|
|
|
|
- `src/repixelizer`: core package
|
|
- `tests`: focused regression tests
|
|
- `docs/spec.md`: product and technical spec
|
|
- `docs/implementation-plan.md`: working roadmap
|
|
- `examples/corpus/README.md`: local corpus layout and attribution workflow
|
|
|
|
Core modules:
|
|
|
|
- `inference.py`: target size and phase inference
|
|
- `continuous.py`: source-aware lattice snapping and local discrete refinement
|
|
- `metrics.py`: fidelity, adjacency, and motif metrics
|
|
- `benchmark.py`: corpus benchmark runner
|
|
- `tuning.py`: black-box hyperparameter search harness
|
|
- `synthetic.py`: facsimile generation for tests and benchmarks
|
|
|
|
## Validation
|
|
|
|
Run the focused test suite with:
|
|
|
|
```powershell
|
|
.venv\Scripts\python -m pytest -q
|
|
```
|
|
|
|
## Notes
|
|
|
|
- The local corpus is optional; the codebase is still usable without it.
|
|
- The benchmark and tuning commands are designed for iterative local work, not for shipping generated artifacts in git.
|
|
- Palette enforcement is optional and can be left off for unconstrained recovery runs.
|