A year ago, I started to research in the field of automating the parsing of receipts data using OCR. I collated a custom dataset of receipt images which are used to train a Document Understanding Transformer model. Using supervised learning, the vision model is capable of learning features from each receipt image and generating a custom JSON document representation of it.
A typical workflow to preprocess the dataset for training works like this:
Collate receipt images from smartphone
Upload images to a custom annotation tool such as UBIAI
Annotate each receipt image by drawing bounding boxes on its name, line items, total spent
Generate a JSON file of the annotation for each image
Write custom python script to parse the JSON document representation for each image into format compatible with Donut Training data format.
Overtime, this manual process can be error prone. The annotation tool needs to be able to detect and handle text bounding boxes appropriately but in some instances, due to actual receipt image quality, it’s not possible to draw the right bounding box in the required region. The running costs of the annotation tool is also high, making it prohibitive for regular usage.
While it is ironic that the trained model is OCR-free, we still need a degree of OCR to preprocess the training images. I started to research into the use of current pretrained vision transformers model to automate some of the preprocessing steps to save costs.
The new data annotation workflow becomes:
Detect and annotate the receipt in a given image automatically
Generate mask of receipt from image
Segment receipt from image
Perform a top-down perspective transform of the receipt
Send receipt image to 3rd party service for OCR Processing
The third step of performing a top-down perspective is important as we don’t want the OCR engine to pick up background features in the image.
1. Detecting receipt in image
For detecting the presence of a receipt in an image, I experimented with using a Grounding DINO pretrained model, which could undertake object-detection with a text prompt. The model is capable of zero-shot inference which means it doesn’t need to be pretrained on a custom dataset. The following is a code sample of using this approach:
To setup GroundingDINO:
The boxes returned are the top-left and bottom-right coordinates of the bounding box. The logits refer to the confidence level of the object detection. We can use the logits as a further level to filter out predictions.
The image below is an example of the model’s prediction:
2. Generate receipt mask
Before we can segment the image, we need to convert the bounding box coordinates from step 1 to be based on the input image size:
To generate the receipt image mask, we could use the Segment Anything model. The SAM model is capable of generating masks for objects in an image given a set of bounding boxes or points. Similar to Grounding DINO, it also has strong zero-shot performance.
We pass the above bounding box coordinates to the Segment Anything model to retrive an image mask for our receipt.
To install the SAM model:
To use the model:
The model returns a mask of the detected object, based on the input box coordinates. The mask image looks as follows:
3. Segment receipt from image
To apply the mask and extract the receipt, we can apply a bitwise and to the original image via OpenCV:
The formatted image looks like this:
4. Top-down perspective transform of image
The processed image from step 3 with the mask applied has the receipt in white against a black background. We can use the cv2.findContours function to find the outline of the receipt and apply a four-point perspective transform to create a top-down view of the image. Lastly, we apply a colour transform to give the image a scanned image look and save the image for processing later:
NOTE: The need to apply a top-down perspective transform is standard practice in OCR. This is to ensure that only the document object exists in the image for analysis and the content of the document object is visible.
NOTE: The above will not work if the receipt has folds/creases in its corners or sides as no contours will be found.
5. Apply OCR to obtain receipt content
Finally, we can pass the scanned image to a 3rd party OCR service to extract the textual content.
For this example, we are testing AWS Textract service as it has a bespoke function for analysis of financial documents including invoices and receipts.
We initialized a boto3 client using the Textract service and pass the local image to it using a bytes array. In production usage, the image should be saved in an S3 bucket and then retrived by Textract with the appropriate IAM permissions.
The returned output is parsed and printed onto the console:
An example output from the service:
A detailed analysis of the Textract response is out-of-the-scope of this article.
In general, the service returns a structured response of the receipt content which includes metadata of the receipt such as the tax code, address and name of business. The line items store the actual items of the receipt which include the item name, quantity and cost price.
Using the response data, we can format it into Donut Training data format, replacing the custom annotation tool.
To fully implement this in AWS, we probably store the original images in an S3 bucket, which can trigger an event whenever a new image is uploaded. The newly uploaded image is then passed to a Lambda function which implements the model logic above. The processed image can be passed onto the Textract service.
Comparision to manual annotation method
The approach outlined above can be automated and scaled to hundreds of images easily using AWS Batch and Lambda. Since the pretrained models provide confidence scores, we can integrate this into a custom pipeline whereby any images that can’t be processed can be marked for manual annotation.
Comparison to using the OCR-Free model
Document Understanding Transformer model is quite capable of generating a representation of a receipt image once it has been trained properly. The approach outlined here is an attempt to automate some of the manual data preprocessing steps to speed up the training process. It’s not designed to be a replacement of the model itself. However, if your requirements are to simply extract content from a receipt, then this approach may suffice.
In production or real-world usage, I can think of situations where the approach mentioned here fails, namely, if the receipt image is creased / folded. The OCR engine will not be able to parse its contents accurately.
The Document Understanding Transformer model is invariant to such defects since it’s trained on ( image, document ) pairs. Given enough training data, the model will be able to generate a full json document representation of an image.
To summarize, I will be testing the automated approach highlighted here in an attempt to preprocess the custom receipt dataset and use it as training features for Document Understanding Transformer model.