Understanding Freeman chain codes for OCR
Master System Design with Codemia
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.
Introduction
Freeman chain codes are a compact way to describe the outline of a binary shape by storing the direction taken at each boundary step. In OCR, that matters because a character's contour carries useful structural information even before you apply more advanced classification methods.
What a Freeman Chain Code Describes
Imagine tracing the edge of a character one boundary pixel at a time. Instead of storing every coordinate, you store only the movement direction from one contour point to the next.
In the common 8-direction version, the code values are:
- '
0for right' - '
1for up-right' - '
2for up' - '
3for up-left' - '
4for left' - '
5for down-left' - '
6for down' - '
7for down-right'
So a boundary walk can be represented as a short sequence such as 0, 0, 2, 2, 4, 6 instead of a long list of pixel coordinates.
Why OCR Pipelines Use Chain Codes
Classic OCR systems often need features that capture shape, not just raw pixel intensity. A chain code helps because it records how the contour turns and how strokes move around the boundary.
That can help distinguish characters that occupy similar bounding boxes but have different outlines. For example:
- '
CandOare both rounded, but one contour stays open and the other closes' - '
LandThave very different direction-change patterns' - '
6and8may share overall size but differ in contour loops and turning behavior'
Chain codes are not a complete OCR system by themselves, but they are a useful contour feature in classical vision pipelines.
Build a Chain Code From Ordered Boundary Points
Suppose contour extraction has already given you the boundary points in order. The following Python example converts those points into an 8-direction Freeman chain code.
This produces the directional sequence that describes the contour path.
Raw Codes Need Normalization
A raw chain code depends on where the contour walk starts and on the image orientation. That means the same character can produce different raw sequences if tracing begins at a different point.
One common improvement is a differential chain code. Instead of storing absolute directions, you store the change in direction between successive steps. That makes the feature less sensitive to the arbitrary starting point of the contour traversal.
Another important step is preprocessing:
- binarization
- noise removal
- connected-component extraction
- boundary ordering
If the contour is noisy or unordered, the chain code becomes unstable and much less useful for OCR.
4-Direction Versus 8-Direction Coding
Some systems use 4-connectivity, where only up, down, left, and right are allowed. Others use 8-connectivity, which also includes diagonal moves.
The 8-direction version is more expressive for handwritten and curved shapes because it captures diagonal contour motion directly. The 4-direction version is simpler, but it may produce a less natural representation for slanted strokes.
Choosing between them depends on:
- the contour extraction method
- the character style
- the rest of the feature pipeline
Common Pitfalls
- Generating contour points out of order, which makes the resulting code meaningless.
- Using raw chain codes without accounting for different starting points.
- Forgetting whether the implementation assumes 4-connectivity or 8-connectivity.
- Feeding noisy boundaries into the feature extractor and expecting stable codes.
- Treating chain codes as a full OCR solution instead of one feature among several.
Summary
- Freeman chain codes represent a contour as a sequence of directional steps.
- In OCR, they help describe boundary shape in a compact form.
- The code is useful only if the contour points are ordered and reasonably clean.
- Differential coding and normalization make chain-code features more robust.
- Chain codes work best as part of a larger OCR pipeline, not as the entire recognizer.

