(CASE STUDY · 04)

GHOST FONT DECODER

  • Computer Vision
  • Optical Flow
  • Python · OpenCV
  • Agent Skills

Ghost fonts hide text in moving dots. Pause the video and every frame is noise. Ghost Font Decoder measures the motion with dense optical flow and returns the text with two images to check it against. It runs from Claude Code, Codex, Claude.ai, a pasted chat prompt or plain Python.

ROLE
Computer Vision & Tooling
TIMELINE
9 Days
YEAR
2026
TEAM
Solo

(MY ROLE)

  • Built the decoder: dense optical flow, background subtraction, drift registration and an Otsu mask, in 303 lines of Python.
  • Packaged it as a ghost-decode skill: plugins for Claude Code and Codex that call decode.py, a self-contained version for Claude.ai, and a chat prompt that needs no install.
  • Wrote the skill's hard rules: one run, two images, never OCR a raw frame.
  • Designed the landing site and the technical docs, and wrote a 19-page handbook and an 11-view C4 model.
(WHY IT EXISTS)
Ghost fonts are marketed as text AI cannot read. Every paused frame is uniform noise; the letters exist only because the dots inside them move against the dots around them. That is a motion problem, and dense optical flow measures motion.
(THE AGENTS DID TOO MUCH)
Agents that doubted the reveal rebuilt the decoder, spawned diagnostic images and called a readable heatmap noise. Every skill now names over-processing as its main failure and rules it out.
(AFTER LAUNCH)
The skill read a second clip, I LOVE YOU, in Claude Code, Claude.ai and Codex, and the pasted prompt read it in Claude and Codex chats. 9 captures ship in the repo as execution evidence.

Process

  1. 01

    Research & Context

    Pinned down what a decoder has to measure: glyph dots and background dots share the same statistics and differ only in motion, the signal is weak per frame pair but strong across the clip, and the letter region drifts.

  2. 02

    Signal & Decoder

    Shipped a 195-line decoder on day one with drift registration already in it, then added a faint-glyph pass, an edge-band filter and a crop that enlarges both images.

  3. 03

    Skill & Agents

    Split the skill for Claude Code and Codex on day one and added the Claude.ai zip on day two. Committing that zip broke the install as a nested zip, so a build script now makes it locally and it stays out of git.

  4. 04

    Proof & Docs

    Built a landing site that answers the AI-proof claim with evidence, then wrote docs that explain the guard thresholds.

How It Works

Attach a clip and ask what it says. The skill runs the decoder once, writes a clean mask and a heatmap, reads both back and answers in one line that starts "Text in the video:".

The Reveal

Two images answer two different questions. The mask shows what reads with confidence. The heatmap shows where the motion evidence is, faint letters included.

In The Detail

The letters drift across the clip while the dots inside them stream past. Phase correlation tracks the drift, and each pair is shifted back before it is added. Without that step the same 184 pairs smear into bands, and the Otsu mask melts the two lines into blobs.

The Decoder

One Python file that Claude Code, Codex and the CLI call. It streams the frames, scores counter-motion pair by pair, registers the drift and writes a clean mask and a heatmap, on OpenCV and NumPy with no model weights. The Claude.ai skill and the chat prompt carry a shorter embedded copy of the same flow, drift and Otsu steps.

(ONE FRAME IS NOISE. 184 PAIRS ARE A MESSAGE.)
A single flow estimate is weak. The same counter-motion recurs over many frame pairs while random error averages out, so the decoder adds up evidence instead of reading any one frame.
(A LONE I)
On the proof clip, a faint I sits alone above LOVE YOU. In decode.py, a second pass at half the Otsu threshold keeps compact faint glyphs, and both images are cropped and enlarged so a single letter is hard to miss.

(SCOPE)

lines of Python in the decoder
303
documented guard thresholds
8
agent runtimes
3

THE GUARDS

Background > 0.15 px
Below it, a direction taken from near-zero motion is unstable, so the pair is scored by residual size instead.
31 × 31 blur
Hides dot-level motion, so phase correlation follows the glyph region, not the dots.
Shift < 30 px
A larger jump between pairs usually means a bad correlation peak, so it is rejected.
0.5 × Otsu
Searches below the global threshold for faint compact glyphs without letting in the noise floor.

Documentation

The docs explain the signal model, the pipeline step by step, and the guard thresholds with the failure each one prevents. A code viewer opens the real files in place. Further down: both outputs, all 6 CLI arguments and what to try when a decode comes back weak.

  1. CLI reference

  2. Outputs

  3. Failure modes

  4. Thresholds