Optical Character Recognition
August 5, 2021 ยท View on GitHub
This module implements the class TrailCamOCR, which is an image-to-text converter for extracting the date, time, and camera serial number fields embedded in an information banner some trail cameras burn into images.
This implementation was designed to work with a particular camera model, the Meidase SL122 Pro, but the approach is fairly general and the code is designed to support adding other cameras. The Meidase SL122 Pro burns an information banner into the bottom of each image. The banner is a gray translucent ribbon with white text.
The algorithm used here works roughly as follows:
- Extract the image blocks where we expect the text to be and perform some image processing operations on the blocks to binarize the block into black and white pixels.
- Count the number of white pixels in the uppermost 60% of the block and also the leftmost 60% of the block, yeilding two numbers. The reason for counting two portions of the block is that several of the digits have similar numbers of white pixels, so just counting all the white pixels in the block is not good enough to discriminate between digits reliably. Experiments were run comparing different counting schemes, and the one described above performed the best for the font used by the Meidase camera.
- Use the k-Nearest Neighbors (k-NN) algorithm to determine the digit. k-NN is a machine learning algorithm that compares the pair of pixel counts to a database of known values.
A dictionary of "codebooks" is used to allow the program to work with the various sizes
of image generated by the camera. Each image size has its own codebook describing the
expected location of each digit, the function to use for decoding this image, and the
name of the k-NN database to use. The exact format of the codebook is described in the
file ocr.py.
If you want to create a k-NN database for your camera, you should start by creating a
new codebook and getting the text box coordinates set up. The class TrailCamOCR has a boolean
class variable called DEBUG_OCR that will be helpful here. When DEBUG_OCR is
set to True, the method digit_meidase will write out each text box as a separate image so
you can determine if the boxes are sized and placed correctly. Next, you can use the
generateTrainingData method to create a data file containing pixel counts.
I load this file into RStudio to graphically examine the data and to test how well k-NN
works with the data. Eventually, you should create a CSV data file containing three
columns -- digit, top, and left -- in that order. Reading through the documentation in the
source code will be helpful for understanding how it all works.