computerFont
A simple machine-readable and human-readable font.

WTF?

Having trouble reading this font? Think of how a computer copes with reading fonts which are comfortable to you!
ESP32 With Camera
Full Fontset
Full Fontset

Why?

This font ("KillAllHumans" made on FontStruct) is a font designed to be both human readable, and easily machine readable.

Getting a machine to read printed information (on paper, in a book or on a sign) is normaly done using QR codes (which are not human readable) or with slow, complex, unreliable and computationally expensive software. Your phone probably has an OCR (Optical Character Recognition) function, but your phone is expensive and the camera is very high resolution. Many apps which do this rely on a network connection back to an OCR server. And you probably have to get fairly close to the sign.

This font is readable to a human, and should be machine readable even with a mediocre camera, processor and limited memory such as the ESP-32 with the camera attachment.

It could be used to provide signposting to assist robotic navigation, or just to label containers in a warehouse for easy identification and location.

Characteristics

Broadly the font is actually a subset of a computer-only font with over 1024 characters, which is not rotatable or reflectable.

  • All characters are 3x4 pixels with a single pixel separating from other characters.
  • No distiction between upper and lower case.
  • All letters are distinct.
  • All digits are distinct.
  • Not all ASCII characters are available.
  • All quotes (single, double etc) are displayed as the same character.
  • Generally, in each character, pixels always populate the top and bottom rows, and the left and right columns (exceptions are minus and vertical bar).
  • Generally, pixels populate every row and every column of the 3x4 space (exceptions are equals, minus, vertical-bar, double-quote).
  • Generally, characters are distinct where possible (exceptions are (zero, alpha), (two, zulu) (five, sierra), (six, beta) (nine, quebec)).
  • Generally, 180-degree rotation characters do not match other characters (exceptions are mike, whiskey).
  • Generally, vertically reflected characters do not match other characters (exceptions are (bravo, delta), (echo, atSign), (sierra, zulu), (lima, romeo) and all brackets).
  • Generally, horizontally reflected characters do not match other characters (exceptions are (bravo, delta), (papa, quebec), (sierra, zulu)).

Software

The approach to writing the software:

  • Try to get the image as horizontal as possible (say within 15 degrees).
  • Rotate the image to maximise variance in the sum of the intensities of the horizontal lines (ie now it will be horizontal)
  • Look for horizontal quarter-beats to identify the horizontal gaps between the columns of letters.
  • Use this scaling to identify the vertical gaps between the rows (or look for 5-beats).
  • Correct the contrast on the grey-scale image to maximize differentiation between white and black pixels.
  • Scale to the 4:5 ratio (ie 3:4 ratio + 1 pixel white space) and just read the pixels.

    ... you get the idea. None of this is computionally expensive, and should be easily doable on an ESP-32 or similar.

    A slightly more sophisticated algorithm would do a simple affine transform and hence work even when the image was taken at a funny angle to the sign. Effectively this would require a 2-D search space for the second step. use
    byte getAffineImagePixel(i,j) { getImagePixel(i, j * x + y); }
    and search on reasonable values of (x, y). Easy!

  • The future

    Actually write the code to demonstrate this.

    Leave a comment

    Something I'm doing wrong? Solved my problems? Got a better idea? Got a similar problem?
    Think I might have solved your problem? Ninety-nine problems, but your robot ain't one? Say so ..