Character recognition: build your own library
Recognize one symbol at a time — drawn or photographed. Name your symbols, draw or upload a handful of samples each, test it live, and download a self-contained zip to host on your own site. No accounts — save gives you a resumable URL. For plain capital letters A–Z, the three ready-made recognizers are smaller and already measured; the home page runs one live.
1 · Library type: characters (words, sentences and the page cleaner later)
2 · Classes & training data
Each class is a symbol your library recognizes. Draw at least 5 samples per class (more = better). Click a thumbnail to delete it.
Train from a zip of character images
Upload one or more .zips of individual character images plus a
manifest.json that labels each image and gives its baseline. Most samples
train; the last few per character measure accuracy. Height is meaningful — measured from
the baseline up (descenders below the baseline don't add to it). Select several zips at
once, or add more later — they combine into one training set (a same-named zip replaces
its earlier version). This builds a photo-input character library.
See the format doc.
manifest.json:
{ "version":1, "xHeight":52, "characters":[ {"file":"a1.png","char":"a","baselineY":140}, … ] }
— xHeight optional (auto-derived from x-height letters if omitted);
add "split":"test" to force a sample into the test set.
Whitespace + dark-pixel combination — experiment
A second recognizer that scores the white space, not the ink: for every
background pixel it measures the distance to the nearest dark pixel and, casting rays, how
far each travels before hitting ink (an angular arm signature that separates * / x / +),
binned into a per-cell spatial-grid histogram and matched by chi-square. Its per-class
probabilities are then blended with the main dark-pixel matcher in log-probability space
— (1−blend)·log Pdark + blend·log Pwhite. Loads the
same character zips above; run once, then slide blend d↔w to remix the two
instantly and find the best mix. A standalone experiment (not part of the downloaded library).
Leave-one-out cross-validation — per-variant accuracy
Runs many training passes over the same character zips above: each time a different drawn variant of a character is held out of the bank and recognized against the rest, repeated until every variant has been the held-out one exactly once. Reports the overall accuracy and, for each variant, its result — the confidence when the correct character ranks #1, otherwise the top-3 guesses with each one's confidence. Uses the matcher's built-in self-exclusion, so one recognizer is built and reused across all hold-outs.
Pair-discrimination heatmaps (baseline frame) — experiment
Which parts of a character carry the evidence that separates it from one specific confusable rival (O vs Q, P vs R)? Pick a good letter and a bad (rival) letter. For every variant of the good letter, its most similar other good variant and most similar bad variant are found (production matcher score, baseline-anchored frame: height above the baseline + distance from the left edge). Then each point is colored by comparing its best point-match into each: dark blue = matches the good template well and the bad one poorly (evidence for the good letter); dark red = the reverse (evidence for the rival); white = matches both or neither (uninformative). Continuous in between. A consistent blue region across variants = exploitable signal for a pair-specific discriminator.
Advanced matcher parameters
Defaults are the swept optima — change only if you know why. Applies to stroke matching; photo matching uses its own tuned set.
3 · Test it
This pad runs the exact runtime + training that ships in your zip.
4 · Save & download
photo-word = reads PHOTOGRAPHS via the WASM matcher + CC lattice, 73 classes (incl. punctuation), 28,770 words with contractions (~0.9 MB, ~2–4 s/word). page cleaner = the other half of the problem and NO recognition: a photo of a page in, clean ink and word boxes out (dewarp, illumination flatten, ruling removal, segmentation; ~170 KB). Detects what kind of paper it is — ruled, plain, graph, dot grid — or you pick. Ready-made; the button above builds a library tuned to your data.