Code reading for Raspberry Pi

Code reading for Raspberry Pi

Summary

This recipe shows how to make an app that reads QR codes and barcodes.

The application targeted at Raspberry Pi, which has rather limited processing power. The standard camera produces 5 MPx images which are too large to be processed in real time as such. Therefore, some speed optimization techniques are introduced.

Downloads

Detailed description

The processing graph is too large to fit one page, which is why we'll walk through it from top to bottom in smaller pieces.

  • The images originate from the default webcam as configured in Image Source. Notice that the default camera is selected automatically by setting the Camera Id as /^webcam/, a regular expression that finds the first webcam connected to the computer.
  • The frame rate is reduced by a factor of 3 with Count and Gate tools. The counter counts from zero to 2 and sets Reset output as True when it wraps around to zero. Reset output is connected to Enabled input of the Gate tool. Gate lets an image pass through from input to output only when Enabled is true. That is, only one out of every three images makes it through. Input parameters table in Gate tool has the name of the output socket (here image) in the first column and the type of the output (here Image) in the second column. The output is connected to three tools as we will see later.
A counter and a gate are used to reduce frame rate.

A counter and a gate are used to reduce frame rate.

  • Convert Colors has been configured to convert the image from color to grayscale. This will speed up the processing downstream because grayscale image has only a quarter of the bytes compared to ordinary RGB color image.
  • We speed up the processing further by cropping the original image to a quarter of its original size. The cropped area will be taken from the center of the original image. JavaScript controls the size and position of the cropped image by calculating Frame and Size accordingly. They are passed on to Crop Image. The downside of cropping is that the barcodes and QR codes will be read only if they are close to the center of the image.
Extracting the center portion of an image with a script and the crop tool.

Extracting the center portion of an image with a script and the crop tool.

Now the processing path is split into three branches. The right one detects and reads barcodes, whereas the left one detects and reads QR codes. The middle branch measures histogram from the cropped grayscale image and analyzes the histogram to find the optimal intensity threshold between dark and bright bars or modules in the code. See the Histogram and Find Threshold tools for details. The user can enable and disable the code reading branches by toggling the enabled input parameters of two gates.

Gates are used to selectively enable/disable code reading branches.

Gates are used to selectively enable/disable code reading branches.

The branches for finding and reading barcodes and QR codes are identical. Let us walk through the one for barcodes.

  • Find Barcode finds the positions of barcodes in the customary Frame and Size format. The intensity threshold between the bars and the background comes from the Find Threshold tool. You can limit the maximum number of codes the detector tries to find with the Max Detections input parameter. The tool outputs sets of Frame and Size matrices which locate the positions and orientations of the found codes.
  • Begin Iterate has been configured to input the sets of frames and sizes from the detector. It splits frame and size matrix sets back to single entities. For instance, assume that there are four barcodes in the image. In this case Iterate Tool splits the 16-by-4 frame matrix into four individual 4-by-4 matrices and the 4-by-2 size matrix into four 1-by-2 matrices.
  • Read Barcode inputs the image and a Frame/Size-locator and reads the code bounded by the box defined by Frame and Size. If you know the code type in advance (e.g. EAN-13, Code128 etc), you can configure it with the Code Type input parameter. This makes the reading faster and more reliable. If you don't know the code type, set the value to Auto-detect which is the default.
The Read Barcode tool will be invoked for each barcode found.

The Read Barcode tool will be invoked for each barcode found.

  • End Iterate is a counterpart to Begin Iterate described above. It stacks up entries received in its inputs, producing either matrices or tables as output. In this example, the entries received at Element 0 input are the code strings and the entries at Element 1 are the code types. If there are, say, four codes found in the original input image, the output at Result 0 will be a 4-by-2 table. Notice that Sync input has to be connected to the corresponding Sync output in Begin Iterate Tool.
  • JavaScript Tool runs a simple script that takes the table of strings and filters out empty ones. This is necessary because sometimes the barcode is easier to find than it is to read. If the reading fails, the reader produces an empty string that is filtered out by the script.
A script is used to filter out failed readings.

A script is used to filter out failed readings.

The processing sequence for the QR code branch is nearly identical. Notice, however, that the code type is set as QR, not Auto-detect like it was in the barcode branch.

QR codes are read the same way as barcodes.

QR codes are read the same way as barcodes.

When both analysis branches are enabled, the app reads QR codes and bar codes simultaneously. The picture below shows a typical result.

Simultaneous reading of perspective-distorted codes.

Simultaneous reading of perspective-distorted codes.