Teaching a machine to read a font built so machines can't
A "ghost font" hides words in moving noise. Screenshot it and the text vanishes. The claim: only human eyes can read it. It took us about twenty minutes and forty-five-year-old math to teach a machine to read it too.
The challenge
Mixfont's ghost font generates a video where text is written purely in motion. Every individual frame is TV static. There is nothing for OCR to latch onto, no letter shapes, no contrast edges, no color. Yet when the video plays, a human reads the words instantly. The effect exploits a deep feature of biological vision: your visual cortex groups pixels that move together, an ability psychologists call the law of common fate. It's the same circuitry that lets you spot a camouflaged animal the instant it takes a step.
We were handed a six-second clip and a claim: machines can't read this. Challenge accepted.
What the machine sees first: nothing
Three checks established what the signal is not, before any decoding was attempted.
Check 3 was motion energy, the difference between consecutive frames. Also uniform: every pixel flickers equally hard, letters and background alike. So naive motion detection fails too. The letters are not "where things move." Everything moves.
The text exists only in motion direction. Inside a letter, pixels drift together. In the background, every pixel drifts randomly. Same amount of motion everywhere, different coherence.
The decode
Once you know the encoding, the attack writes itself: measure the motion vector of every pixel between every pair of consecutive frames, then average those vectors over the whole clip. Background pixels get a different random direction each frame, so their vectors cancel toward zero. Letter pixels drift consistently, so their vectors add up. The magnitude of the averaged motion field is the hidden text.
The per-pixel motion estimate is Lucas-Kanade optical flow, a classical computer-vision method published in 1981. About twenty lines of numpy:
for each frame pair (I0, I1):
Ix, Iy = spatial gradients of I0
It = I1 - I0
solve per pixel over an 11px window:
[ Σ Ix² Σ IxIy ] [vx] [ Σ IxIt ]
[ Σ IxIy Σ Iy² ] [vy] = - [ Σ IyIt ]
accumulate (vx, vy)
text = |mean flow vector| per pixel
Result, first clip:
Second clip, same tool, zero tuning:
The dead ends (kept honest)
- Time-average image: noise. The font adds no luminance bias.
- Per-pixel variance over time: flat. Every pixel varies equally.
- Motion energy: flat. Flicker amplitude is uniform by design.
- 1-D horizontal flow, averaged: near zero. The glyph drift direction wanders over the clip, so assuming one fixed direction partially cancels. The fix was full 2-D flow vectors, averaged as vectors, magnitude taken at the end.
Does it use AI?
No, and that is the interesting part. The decoder is deterministic linear algebra: no model, no weights, no training, no inference. Same video in, same image out, on any machine. An AI assistant designed and debugged the method, forming hypotheses, running the checks above, discarding the dead ends, but the method it produced is pure 1981.
That's the lesson worth teaching. Any scheme whose security or "humans only" property rests on machines lacking a human perceptual channel should assume the channel can be mechanized, usually with math that has existed for decades. The ghost font's premise survived twenty minutes of directed analysis.
Run it yourself
The full decoder, a CLI that takes a file or URL, a paste-a-URL web page, and the complete build notes (dead ends included) are open source. Generate your own ghost video at mixfont.com and feed it in.
redeyesecurity / read_ghost →