QR Code reading with HALCON Embedded on a Raspberry Pi 3

In this proof of concept, we want to show you how to easily integrate a QR code reader on an embedded device using HALCON and HDevEngine.


Hardware license: Solderpad 0.51   Software license: COTS

Documentation

In this proof of concept, we want to show you how to easily integrate a QR code reader on an embedded device using MVTec HALCON and HDevEngine. In our example, we used a Raspberry Pi 3 Model B with the standard camera module v2.

Prerequisites

  • Rasperry Pi 3 running Raspbian
  • Raspberry Camera incl. a mounting device to attach it to the RPi case
  • MVTec HALCON to create the machine vision application on your desktop machine (You can download a free trial version at www.halcon.com/now)
  • MVTec HALCON Embedded for Raspberry Pi
  • HALCON 12 Video4Linux2 driver (You can download the driver after signing up for a free Customer Account at mvtec.com. You can use the account you have created for downloading the HALCON Trial Version)
  • Any ftp client or usb thumb drive for transfering the source files onto the RPi
  • Makefile to build the application for the desired target platform (ARMv8)

Creating the machine vision part with HDevelop

In the final application, we want to use two HDevelop procedures: One that initializes the camera and the data code reader, and one that finds the data codes (in our case, QR codes) and returns a result message. Let's have a look how easily these procedures can be created using HDevelop.

First, we create the procedure init_acquisition.hdvp. Here, we open and configure the image acquisition device. The output variable AcqHandle can later be used to grab images of the camera.

  open_framegrabber ('Video4Linux2', 4, 4, 0, 0, 0, 0, 'default', -1, 'gray', -1, 'default', 'default', 'default', -1, -1, AcqHandle)

Secondly, we create the handle for the data code reader. We specify that we want to detect QR codes.

  create_data_code_2d_model ('QR Code', [], [], DataCodeHandle)

Thus, the output of this procedure are the handles AcqHandle and DataCodeHandle.

Then, we create the procedure find_qr_code.hdvp. Here, we grab an image using the AcqHandle.

  grab_image (Image, AcqHandle)

Then, we find QR codes in this image using the DataCodeHandle.

  find_data_code_2d (Image, SymbolXLDs, DataCodeHandle, [], [], ResultHandles, DecodedDataStrings)

The rest of the program simply assembles the output message, that we want to return in a shell.

  get_system_time (MSecond, Second, Minute, Hour, Day, YDay, Month, Year)
  Date := Year + '-' + Month + '-' + Day $ '.2d' + ' ' + Hour $ '.2d' + ':' + Minute $ '.2d' + ':' + Second $ '.2d'
  if (DecodedDataStrings == [])
      ResultMessage := 'No QR code found.' + ' (' + Date +  ')'
  else
       ResultMessage := 'Decoded QR code(s): ' + DecodedDataStrings + ' (' + Date +  ')'
  endif

Incorporating these procedures in a C++ project using HDevEngine

In the C++ project, we use these HDevelop procedures directly, with HDevEngine. First, we define the location of the procedures.

  std::string ext_proc_path = "./hdevelop_procedures";
  HDevEngine().SetProcedurePath(ext_proc_path.c_str());

Then, we call the first procedure and get the output variables.

  HTuple  acq_handle;
  HTuple  data_code_handle;
  InitializeAcquisition(acq_handle, data_code_handle);

The function InitializeAcquisition looks like this:

  HDevProcedure     proc("init_acquisition");
  HDevProcedureCall proc_call(proc);
  proc_call.Execute();
  proc_call.GetOutputCtrlParamTuple("AcqHandle", &acq_handle);
  proc_call.GetOutputCtrlParamTuple("DataCodeHandle", &data_code_handle);


Similarly, we call the second procedure in a loop to find the QR codes and return a result message.

  while (keepRunning)
      {
          HString         result_message;
          FindQRCodes(proc, acq_handle, data_code_handle, result_message);
          printf(result_message);
          printf("\n");
    }

Building the application

When building and running the application, we need to set some parameters. Thus, we created a simple setup.env file.

  export HALCONROOT=$(pwd)/halcon
  export HALCONARCH=armv7ahfneon-linux-gcc48
  export PATH=$HALCONROOT/bin/$HALCONARCH:$PATH
  export LD_LIBRARY_PATH=$HALCONROOT/lib/$HALCONARCH

  export NATIVE=yes
  export DISPLAY=192.168.0.1:0
  export XLOCALEDIR=$(pwd)/arm-xilinx-linux-gnueabi/share/X11/locale
  export LD_LIBRARY_PATH=$(pwd)/arm-xilinx-linux-gnueabi/lib:$LD_LIBRARY_PATH 
  # To use the Video4Linux API, load the driver
  sudo modprobe bcm2835-v4l2

The result

When executing the application, the output looks something like this:

Reading QR codes on Raspberry Pi 3 with MVTec HALCON Embedded

 

Raspberry Pi 3 reading QR codes

Note: If more QR codes are within the camera's field of view, the QR code reader uses the code with the best quality.

The Raspberry Pi 3 running the QR code reader

The Raspberry Pi 3 with the camera module

 

Does this project pique your interest?
Login or register on Imaginghub to join or follow this project.