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.
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.
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
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"); }
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
When executing the application, the output looks something like this:
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 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 |
You'd like to participate ... Show more