Concepts
Palette Histogram Match
A free +0.55 on the VLM judge from a CPU postprocess that runs in under 100ms
Even with a good seed and a careful pipeline, the painted side of a tile drifts a little in colour. Not enough to look broken, but enough to read as "two photos pasted together" instead of one image. A standard image-processing trick — match the colour distribution of the output to the seed — closes most of that gap, for free, on the CPU.
Drag the slider
Slide from 0% (raw FLUX output) to 100% (full histogram match against the seed). Watch the histogram on the right migrate toward the seed's shape, and the tile preview drift back toward the seed palette.
How the trick works
For each colour channel (R, G, B), build a cumulative distribution of pixel values in the seed and in the output. Then remap every pixel in the output to the value that has the same cumulative position in the seed. The rendering content stays put — only the tone curve shifts.
Build CDFs
Per channel, count pixel intensities into bins and accumulate. Two CDFs: one for the seed strip, one for the output tile.
Map values
For every output value v, look up its CDF position in the output, then find the seed value with the same CDF position. Replace v with that seed value.
Recombine
Three remapped channels stacked back into an RGB image. No model call, no GPU, no learnable parameters. skimage.match_histograms does this in one line.
A flat colour transform (LUT, white balance, saturation) shifts every pixel by the same rule — it can't fix mid-tone drift without crushing highlights. Histogram matching is per-percentile: pixels that were in the bottom 20% of green in the output become the bottom 20% of green in the seed, regardless of their absolute value. That preserves local contrast while rebuilding global tone.
Real numbers from iter-8
Stacked on top of the iter-5b stack with no other changes. Some biomes barely move; others — particularly tightly-toned ones like dungeon stone — shift dramatically.
When it doesn't help
- Tiles where the output and seed share the same palette already (no drift to fix).
- Tiles where the structural error is the dominant problem — palette match makes a wrong-shape river the right colour, but it's still the wrong shape.
- Style transfers across biome boundaries (matching a desert tile's histogram to a forest seed produces unnatural greens).
How this is built (technical)
Postprocess uses skimage.exposure.match_histograms(output, reference, channel_axis=-1) against the seed strip cropped from the anchor. Runs CPU-side after image generation, before VLM
evaluation. End-to-end cost on a 1024² tile is ~80ms on a single core. Implemented in scripts/spikes/palette_match.py; results visualised per-biome in scripts/spikes/_research/palette_match_visual_analysis.md.