Repository navigation
How It Works
Every image pixel becomes a 4 × 4 cell of printer dots (1/150 inch at 600 dpi).
- How many of the 16 dots are inked sets the gray level → the brightness of the photo.
- Which corner the ink leans towards carries 2 bits of data.
Inside each cell the dots are placed where the full-resolution photo is darkest, so edges stay sharp, while the ink's centre of mass still leans clearly enough towards the data corner. At reading distance the eye just sees a normal halftone.
- The photo's color (Cb/Cr) is reduced to 1/8 resolution and 6 bits per value. People see brightness detail far better than color detail, which is why JPEG and TV do the same.
- It is protected with Reed-Solomon error correction and repeated across the page as often as space allows.
- A fixed, public permutation scatters every byte over the whole sheet, so a smudge, a fold or handwriting never wipes out one region. Nothing is secret: the seed is part of the open format.
A thin black border lets Inkhue find the page in a scan and correct tilt and perspective; a timing track of alternating cells tells it the grid size. If a pen stroke confuses the count, neighbouring sizes are tried and the Reed-Solomon check on the header confirms the right one.
- Find the frame, straighten the page, resample it to one pixel per printer dot.
- For every cell: count the ink (brightness) and measure where its centre lies (the 2 bits).
- Combine all copies of every bit, correct errors, rebuild the low-resolution color.
- Neural refiner: a small U-Net (about 1 million parameters, runs on the CPU with ONNX Runtime) reads the scan dot by dot and the decoded color, removes halftone grain, corrects toner spread, sharpens the color along brightness edges and outputs the photo at 2× the cell resolution — 300 ppi for a 600 dpi print. It was trained on the DIV2K photo set through a simulated printer and scanner.
Pages must still decode years from now. The format constants (above all the scatter SEED) are frozen and pinned by tests/test_format.py; a format change needs a new version number and a decoder that still reads the old one.
- R. L. de Queiroz, K. M. Braun — Color to Gray and Back, IEEE TIP 2006
- M. Xia, X. Liu, T.-T. Wong — Invertible Grayscale, SIGGRAPH Asia 2018
- M. Tancik, B. Mildenhall, R. Ng — StegaStamp, CVPR 2020
Using Inkhue
Inside
中文