So once the technique is known by the model the font stops working as intended.
EDIT: To be clear, I'm talking about the "Written in Morse Code" example, fully hallucinated text. The AI agents seeing a decoy message isn't as bothersome to me.
https://qri.org/blog/psycrypto-contest
https://www.youtube.com/watch?v=oD4nV0CMkBI
Of course, the psychedelic hidden message is reversible with some video processing techniques for everyone else to see. And calling it cryptography is a mis-use of the term. Still an interesting use of the effect.
I don't think "ghost font" will work as well as the author claims.
Edit: looks like yes, from the shared chats people are posting. But it’s interesting to think of communication schemes that require a temporal component so any single image is unreadable and can’t be beaten by long exposures or other tricks (otherwise persistence of vision displays would satisfy). A sort of physical anti copy/paste.
If the string is empty, I can read "WRITTEN IN GHOST FONT" very faintly. I'm guessing that is a watermark Edit: Ah, it's decoy text. Of course.
It's interesting work for sure, but the end goal of separating out AI versus human consumers is tough. Indeed, if there was a lasting solution, that would be a substantial discovery that would quickly become very famous...
strong statement, I struggle to read it
The ADA suits will be absolutely hilarious and honestly, I can’t wait.
Also
lol. Barely.
How about writing or drawing stuff using optical illusions?
Shapes that not even human eyes can see, but the brain hallucinates: Shapes that seem to appear when you look straight at a pattern, or for a second after you look away from a pattern, or after you close your eyes, etc.
If you take a screenshot or a photo the image would just contain the same static pattern.
i.e. qualia-based "cryptography" :)
Furthermore, if AI can read this or not depends on how the text sequence is pre-processed. If AI only gets snapshots of the text, it will probably fail in decoding the text as every snapshot contains only white noise and such no information. However, if we calculate the Deltas between the animation frames, the text will become decodable by an AI, you probably don't even need LLMs or CNNs for this.
It seems to me like it should be easy enough to take Ghost Font, apply normal video compression techniques, and analyze the compressed signal to recover the visual outline of the letters, which you would then analyze with OCR (or an AI I guess ...). In other words, a novel CAPTCHA technique but not necessarily "fundamentally more difficult" than existing CAPTCHA techniques, once the cat-and-mouse game gets going.
I can barely read the actual message, and it's about as "readable" to me as the Magic Eye 3D pictures. Actually I think I have a headache from looking at it on a mobile screen.
As a research idea it's cool though. But I do wonder if/when AI models will figure out how to decode it - I imagine a bit of additional prompting would get them there.
WHAT HAPPENS IN VEGAS
STAYS IN VEGASSo...usefulness?
- "This game disappears if you pause it": https://youtu.be/Bg3RAI8uyVw
- "Illusion: If You Pause, The Image Will Disappear": https://youtu.be/ZqGfb_Vlrig
Took a picture (only a single frame) and a 1s movie and threw it toward GPT 5.6 Sol (High):
Frame took 9m30s to decyper and GPT 5.6, it returned: WRITTEN IN GHOST FONT. Weird because I can only see "GHOST FONT" on the demo... but extracted data from image (I saw the highlited one) definitely looks like the "Ghost Font".
--
Video is more amusing, because after 3m GPT 5.6 figured it's motion-defined and asked to run QuickTime. At one moment I got:
> The animation is a motion-defined illusion. I’ve confirmed there’s no readable static OCR layer; I’m decoding its optical-flow field so the letter shapes become explicit.
At 4m it got extracted motion image that was in shape of letters but analyzed for 9 more letters and returned (at 13m36s) "GHOST FONT"
--
So:
a font... - FALSE - not a font, but video effect
...humans can read... - FALSE - I can't read it from image (but AI can!)
...but AI cannot - FALSE - it can
:DEdit: https://imgur.com/a/SHlGu4O - work-in-progress images
"フㄖ乇ㄚ ᗪㄖ乇丂几'ㄒ 丂卄卂尺乇 千ㄖㄖᗪ"
However, I have noticed that voice assistants have a hard time understanding homonyms. Saying "bow" (as in to bow one's head) is often stored as "bow" (as in a bow and arrow). I wonder if there's a sufficiently complex sentence which is intelligible to humans but not to machines?
"A computer font or digital font is a digital data file containing a set of graphically related glyphs"
so it's not a font, humans can't read it and AI can.
That still makes it (well, a future version) potentially useful as a captcha if we hate our users but hate AI more.
Skill issue on promoter side.
Fable oneshotted it for me.
""" Reveal a motion-camouflaged message hidden in video noise.
How it works: The background noise scrolls vertically at a constant rate (a few px/frame), while the noise inside the letters does not follow that motion. Any single frame looks like pure static. The decode is:
1. Estimate the background's global motion between consecutive frames
with phase correlation (this is the "optical flow" step - the motion
is a pure translation, so one global vector suffices).
2. Motion-compensate: shift frame t+1 back by that vector so the
background lines up with frame t.
3. Take the absolute difference. The background cancels almost
perfectly; the letters (which don't move with the background)
light up.
4. Average the residual over a SHORT window of consecutive frame pairs
(long windows smear the letters, because the text itself drifts
slowly over time), blur lightly, and threshold with Otsu.
Usage:
python reveal_hidden_message.py input.mp4 [output.png]
"""import sys import cv2 import numpy as np
PAIRS = 5 # number of consecutive frame pairs to average (keep small!) BLUR_SIGMA = 6 # spatial blur of each residual, in pixels START_FRAME = 0 # where in the video to start
def load_gray_frames(path, count): cap = cv2.VideoCapture(path) frames = [] while len(frames) < count: ok, frame = cap.read() if not ok: break frames.append(cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY).astype(np.float32)) cap.release() if len(frames) < 2: raise SystemExit("Could not read enough frames from the video.") return frames
def main(): if len(sys.argv) < 2: raise SystemExit(__doc__) src = sys.argv[1] dst = sys.argv[2] if len(sys.argv) > 2 else "revealed_message.png"
frames = load_gray_frames(src, START_FRAME + PAIRS + 1)
h, w = frames[0].shape
acc = np.zeros((h, w), np.float32)
for i in range(START_FRAME, START_FRAME + PAIRS):
a, b = frames[i], frames[i + 1]
# 1) global background motion between the two frames
(dx, dy), response = cv2.phaseCorrelate(a, b)
dxi, dyi = int(round(dx)), int(round(dy))
print(f"pair {i}: background shift = ({dx:+.2f}, {dy:+.2f}) px, "
f"response = {response:.2f}")
# 2) motion-compensate frame b by integer (dxi, dyi), then
# 3) residual = |a - b_shifted| on the overlapping region
ys = slice(max(0, -dyi), min(h, h - dyi))
xs = slice(max(0, -dxi), min(w, w - dxi))
ysb = slice(max(0, dyi), min(h, h + dyi) if dyi < 0 else h)
# simpler: crop both to the common overlap
a_ov = a[max(0, -dyi):h - max(0, dyi), max(0, -dxi):w - max(0, dxi)]
b_ov = b[max(0, dyi):h - max(0, -dyi), max(0, dxi):w - max(0, -dxi)]
resid = cv2.GaussianBlur(np.abs(a_ov - b_ov), (0, 0), BLUR_SIGMA)
acc[:resid.shape[0], :resid.shape[1]] += resid
# 4) normalize + Otsu threshold + light cleanup
u8 = cv2.normalize(acc, None, 0, 255, cv2.NORM_MINMAX).astype(np.uint8)
_, mask = cv2.threshold(u8, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)
kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (5, 5))
mask = cv2.morphologyEx(mask, cv2.MORPH_CLOSE, kernel)
out = 255 - mask # black text on white
cv2.imwrite(dst, out)
print(f"wrote {dst}")
# optional: OCR if pytesseract is installed
try:
import pytesseract
text = pytesseract.image_to_string(out, config="--psm 6").strip()
print("OCR result:\n" + text)
except ImportError:
pass
if __name__ == "__main__":
main()Wait, what? Seriously? That’s the only text I can see. Am I an AI?
HackerNews never disappoints
“Not just image. The sound also disappears when you pause”
Brilliant :)
(so either I am AI at a level less than Opus 4.8 or just all-round defective as a human)
It's a static decoy message independent from what you type in. You can see it if you take a long exposure pic of the screen (e.g. with your smartphone).
Relevant xkcd: https://xkcd.com/2793/
And this thread is seemingly full of people claiming AI can read it while simultaneously sharing that AI could not read the actual message, only the decoy as demonstrated in TFA.
I found the bot living in a simulation!
What do I win? Where's my prize?
The text is a video. Every frame contain random dots, so an individual frame by itself doesn't contain the intended message
This "font" exploits the fact that current-gen frontier models will process video one frame at time, but each frame is noise, so by looking at frames in isolation doesn't reveal anything
Then, they add a hidden message to each frame just so that the agent report something and stop trying (because if the agent tried to correlate between the frames, they could discover the trick)
But if you pass just a frame, there is no message. Just the noise plus the decoy
EDIT: On second look, the static screenshot does say "WRITTEN IN GHOST FONT".
My phone would have been zooming out the browser window, and making the dots even tinier, but the phone is HiDPI so it would have still preserved the dots. My eyes are middle-aged and probably starting to do the same kind of median-blur effect that models do when they resize an image. That's my current guess for why I can see the decoy more clearly on mobile.
If that's the case, then this trick will stop working as vision models approach pixel-perfect vision, instead of the current resizing that they do. Pretty cool as steganography though.
https://i.imgur.com/CgtyGjl.png
From a single frame you can definitely identify boundaries because the dots are sliding and get truncated.
So there are two texts, one decoy (which you can barely see in a single frame but becomes more clear if you average between frames) and an actual text, which disappears in single frames or averaged ones.
An anti-AI font that can be read by humans but not leading AI models. Type your text below, then download and share the video clip containing your message.
Write your message:10/36
Speed120px/s
Ghost Font is an anti-AI font that writes a message using motion. Using a combination of motion, video, noise, and decoys, it's a unique way to share a message with other real humans. I suppose technically, it's not a font in the traditional sense of a TTF font file. But, Ghost Font is an experiment of a way to graphically communicate in writing in a format that AI cannot easily understand. While it's not as legible as regular text, the letters are still immediately readable to a human eye, but even leading AI models can't decipher it easily.
Your browser does not support the video element.
Example video generated with Ghost Font.
Videos generated with Ghost Font were then passed to leading AI models like Claude Fable and GPT Sol 5.6 Ultra. Even these recent agents, with the ability to code, struggled to decode the moving message until prompted with the exact technique to look for.
The playground above is just a prototype of this concept. Type a few words and the letters appear but only because the motion of the dots is visible to a human eye.
When the video is paused, the static dots blend together, and it becomes impossible to tell just from looking at a single frame what message is embedded in the image. That means that screenshotting the page won't reveal the message.
This experiment works locally—type the message and preview it live, or download the video to share and test it out yourself. The data is not shared or sent to any server.
In 2013, designer Sang Mun released a font called ZXX. It was a typeface with four fonts designed to be readable by humans but not by optical character recognition (OCR) software. The letters were camouflaged with noise, crossed out, and buried under false marks. At the time, this font was deemed "surveillance-proof"—but fast forward to today, and modern AI agents can easily read text rendered in ZXX.
Example of the ZXX font
While this might have defeated OCR software in 2013, modern AI models can read the text in ZXX pretty easily. I copied this image into ChatGPT 5.5 on Instant mode, and it was still able to get the words including some small details as well in a single prompt:
ChatGPT easily reads the text in this image
However, the same process with Ghost Font won't work quite as easily. A single screenshot of Ghost Font will yield just a completely static image with no readable text. That's because every letter in Ghost Font is made up of dots that look exactly like the background, so any single image from the video will not reveal anything about the message:
Trying ChatGPT 5.5 Pro with Ghost Font
After a 19-minute analysis, ChatGPT 5.5 Pro hallucinated a message that doesn't exist.
However, simply hiding a message in a video isn't a perfect solution. While an online model environment might not be able to get it from individual frames, a dedicated agent that has a local code execution environment can still analyze the motion of the dots and decode the message. Ghost Font solves this in another layered way: a decoy message is included in every video generation.
The decoy message serves as a final trick for a determined agent. When looking for a hidden message, it might first find the decoy message and think that that is the real embedded message in the video. That's how Ghost Font is able to hide a message even from the strongest thinking models like Fable and GPT Sol 5.6 Ultra.
Ultimately, the way to truly hide a message is to use encryption, or some sort of key. No AI will be able to read a message that requires a specific password to unlock that only humans know. However, this project explores whether it's possible to create a shareable file containing a visual message that can't be easily read by AI models.
We created this experiment as a way to explore the limits of AI perception while also preserving something human. As AI takes over font generation, our hope is that humans will continue to have a unique creative voice.
There are certain implications for Ghost Font that I think would be interesting to continue to explore. For example, it would be interesting to incorporate Ghost Font into CAPTCHA systems, as most systems are easily solved by AI today. Using motion in a video would be a way to make it much more difficult for an automated bot to decipher but still relatively easy for a human to read.
Ghost Font might also be an interesting way to benchmark AI progress when it comes to visual perception. Right now, multimodal models are image-based, and even when passed a video, they usually split the video into frames and analyze individual frames. In the near future, I assume there will be a video-native model that will be able to read the text directly.
A final lesson is that AI is certainly getting really good. While Ghost Font is hard for AI to read, it's also pretty hard for humans to read! The gap continues to close. It will be interesting to see what the future holds when it comes to AI perception and multimodal models.
As a next step, I plan to release the code for the video generation as an open-source project—stay tuned for that! I also hope to expand the size and handle longer text strings. I hope you enjoyed this experiment and I would love to hear your thoughts. You can find me on X at @ericlu.
- Eric