Etairos github / read_ghost
Lab Notes

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.

By Matt Lucas · RedEye Security / Etairos · July 14, 2026

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.

A single frame of the ghost font video: pure static, no visible text
Check 1: any single frame. Full-range noise. Nothing readable, as designed.
The average of all 187 frames: flat noise with only the faintest smudge
Check 2: average all 187 frames. Still noise. So the text is not a hidden brightness bias, averaging would have revealed that instantly.

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:

Decoded output clearly reading HELLO HUMAN
Decoded. The clip says HELLO HUMAN.

Second clip, same tool, zero tuning:

Decoded output clearly reading ETAIROS CAN SEE
Decoded. ETAIROS CAN SEE.

The dead ends (kept honest)

  1. Time-average image: noise. The font adds no luminance bias.
  2. Per-pixel variance over time: flat. Every pixel varies equally.
  3. Motion energy: flat. Flicker amplitude is uniform by design.
  4. 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 →