Perfect Pixel (Grid Restore)
The node that turns muddy AI pixel art into clean grids
- image
- image
You've made AI pixel art. You know the problem: it reads as pixel art from across the room, and up close it's a blurry watercolor - every "pixel" has gradient edges, the grid lines wobble, and there's color noise in the cells. Perfect Pixel (Grid Restore) is the node built for exactly that job. It finds the real grid hiding in your image, snaps each cell to a single clean color, and re-exports the whole thing at crisp, nearest-neighbor resolution.
Set expectations before you install it. This is cleanup, not upscaling-in-the-generative-sense: it will not invent detail that isn't there (no SeedVR2 vibes here), and it's useless on photographs or anything that isn't actually gridded. But for "my diffusion model turned 32x32 pixel art into a smudge," it's the one tool that does the thing nothing else does.
How it works
The node is a ComfyUI wrapper around theamusing's algorithm, and the mechanism is genuinely clever. First it estimates the grid: it converts to grayscale, runs an FFT, and looks for a dominant spatial frequency in the shifted magnitude spectrum - the signature of a regular grid. That gives a first guess at cell size. If FFT detection fails or the result looks inconsistent (the code sanity-checks for cells between ~4px and ~20px), it falls back to a Sobel-gradient profile: sum edge strength down every column and across every row, and the peaks mark where the grid lines actually are. Either way, it then snaps each estimated line to the nearest real edge in the gradient.
Next, sampling collapses every cell to one color. Center Sample just grabs the pixel at the cell's middle - fastest, fine for clean sources. Majority Cluster (the default) runs a 2-cluster K-Means on each cell's pixels and keeps the color of the larger cluster, which is what kills gradient transitions and noise. The result is a tiny, clean grid - often 64x64 - which the node scales back up with nearest-neighbor interpolation, so every edge stays exactly one hard pixel wide instead of getting re-blurred. Nice touch: if grid detection fails entirely, the code just hands your original image back unchanged rather than mangling it.
The inputs that matter
There are only four, and you'll probably touch two of them:
- sampling -
Majority Cluster(default, recommended) orCenter Sample(fastest, slightly noisier output). - export_scale - default
4, range 1–16. This is how big your restored grid comes back. Leave it at 4 unless you know the original's native cell count. - backend -
Auto(default),OpenCV Backend,Lightweight Backend. Auto prefers the fast C++ OpenCV path and drops to the pure-NumPy reimplementation if cv2 isn't importable, so the node degrades gracefully. - image - your pseudo-pixel art in, a clean
imageout. Wire the output straight into SaveImage.
Installing it
Easiest is ComfyUI Manager: search PerfectPixel (pack title ComfyUI-PerfectPixel) and install. Manually:
cd ComfyUI/custom_nodes
git clone https://github.com/AharaOoO/ComfyUI-PerfectPixel
cd ComfyUI-PerfectPixel
pip install -r requirements.txt
Then restart ComfyUI - the node lives under image/postprocessing. Two real-world notes. First, the README's own clone URL is typo'd (AchengOoO instead of AharaOoO) - don't copy-paste it, use the URL above or Manager. Second, requirements.txt is just opencv-python-headless; it's the only dependency, so this is a light install even by custom-node standards.
Gotchas
- The name is a collision magnet. A1111's ControlNet had a "pixel perfect" toggle that auto-matches input sizes - a completely different thing. Most search results for "pixel perfect ComfyUI" are about that, not this node. There is effectively no dedicated community discussion of this node yet, so treat it as the solid-but-unknown tool it is.
- Only feed it real pixel art. On a non-grid image it either passes the input through unchanged or quantizes something that shouldn't be quantized.
- Watch the batch. The node raises an error if images in a batch come out different sizes; feed frames one at a time if you're processing a sprite sheet.
- It adds no detail. If your art is small and dirty, run this first to get a clean grid, then a real upscaler on top. The clean grid upscales far better than the muddy original ever will.
Inputs (4)
| Name | Type | Default | Description |
|---|---|---|---|
| image | IMAGE | — | |
| sampling | COMBO | Majority Cluster | 2 options: Majority Cluster, Center Sample |
| export_scale | INT | 41–16 | — |
| backend | COMBO | Auto | 3 options: Auto, OpenCV Backend, Lightweight Backend |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| image | IMAGE | — |