Shards pattern

QR Code reading with HALCON for ARM 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.

Project State

Public Project

Licences

Software Licence: COTS
Hardware Licence: Solderpad 0.51

Project Tags

Admins

mvtecsoftware

Members

bindertom

Does this project pique your interest?

Login or register to join or follow this project.

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 for ARM-based Platforms (www.mvtec.com/products/halcon-embedded/arm/)
  • Video4Linux2 interface (use the driver that is included in the HALCON for ARM-based Platforms installer)
  • 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

 

Title Description Format
find_qr_code C source code of the find_qr_code application cpp
find_qr_code HALCON procedure for finding and reading QR codes hdvp
init_acquisition HALCON procedure for initializing image acquisition from the camera hdvp

Comments

Your comments, please!

Want to comment this ... Show more Arrow right