Python Barcode Decoding on Non-Python Created Thread

Xiao Ling
3 min readJul 7, 2019

--

Dynamsoft Barcode Reader 7.0 brings a set of thread-based APIs for continuous frame management and corresponding barcode decoding. It extremely simplifies the programming complexity, especially for Python. It is known that Python’s GIL ( Global Interpreter Lock) affects the performance in a multi-threaded scenario. Running computation intensive tasks in Python thread cannot improve the Python app performance. If you create a Python barcode scanner app with OpenCV and Dynamsoft Barcode Reader 6.x, Python multiprocessing is the only way for getting a high camera frame rate. With the thread-based APIs of Dynamsoft Barcode Reader 7.x, your Python apps will not be limited by GIL anymore. This tutorial shares how to integrate the thread-based C/C++ APIs into Python barcode extension.

The New Barcode Decoding APIs for Video Frames

To read barcodes from continuous frames, you need to use following APIs:

  • DBR_StartFrameDecoding()
  • DBR_StopFrameDecoding()
  • DBR_AppendFrame()
  • DBR_SetTextResultCallback()

DBR_StartFrameDecoding()

Starts a new thread to decode barcodes from the inner frame queue.

Parameters:

[in]    barcodeReader   Handle of the barcode reader instance.[in]    maxListLength   The max count of frames waiting for decoding.[in]    maxResultListLength The max count of frames whose results (text result/localization result) will be kept for further reference.[in]    width   The width of the frame image in pixels.[in]    height  The height of the frame image in pixels.[in]    stride  The stride of the frame image (also called scan width).[in]    format  The image pixel format used in the image byte array.[in]    pTemplateName   The template name.

Returns:

Returns error code. Returns 0 if the function operates successfully, otherwise call DBR_GetErrorString to get detail message. Possible returns are: DBR_OK; DBRERR_FRAME_DECODING_THREAD_EXISTS; DBRERR_PARAMETER_VALUE_INVALID; DBRERR_NULL_POINTER;

Code Snippet:

void* barcodeReader = DBR_CreateInstance();DBR_InitLicense(barcodeReader, "t0260NwAAAHV***************");int errorCode = DBR_StartFrameDecoding(barcodeReader, 2, 10, 1024, 720, 720, IPF_BINARY, "");DBR_DestroyInstance(barcodeReader);

DBR_StopFrameDecoding()

Stops the frame decoding thread created by StartFrameDecoding.

Parameters:

[in]	barcodeReader	Handle of the barcode reader instance.

Returns:

Returns error code. Returns 0 if the function operates successfully, otherwise call DBR_GetErrorString to get detail message. Possible returns are: DBR_OK; DBRERR_STOP_DECODING_THREAD_FAILED;

Code Snippet:

void* barcodeReader = DBR_CreateInstance(); DBR_InitLicense(barcodeReader, "t0260NwAAAHV***************"); 
int errorCode = DBR_StopFrameDecoding(barcodeReader); DBR_DestroyInstance(barcodeReader);

DBR_AppendFrame()

Append a frame image buffer to the inner frame queue.

Parameters:

[in]    barcodeReader   Handle of the barcode reader instance.[in]    pBufferBytes    The array of bytes which contain the image data.

Returns:

Returns the Id of the appended frame

Code Snippet:

void* barcodeReader = DBR_CreateInstance(); DBR_InitLicense(barcodeReader, "t0260NwAAAHV***************"); 
int frameId = DBR_AppendFrame(barcodeReader, pBufferBytes); DBR_DestroyInstance(barcodeReader);

DBR_SetTextResultCallback()

Sets call back function to process text results generated during frame decoding.

Parameters:

[in]    barcodeReader   Handle of the barcode reader instance.[in]    cbFunction  Call back function.[in]    pUser   Customized arguments passed to your function.

Returns:

Returns error code. Returns 0 if the function operates successfully, otherwise call DBR_GetErrorString to get detail message. Possible returns are: DBR_OK; DBRERR_FRAME_DECODING_THREAD_EXISTS;

Code Snippet:

void TextResultFunction(int frameId, TextResultArray *pResults, void * pUser){//TODO add your code for using test results}void* barcodeReader = DBR_CreateInstance();DBR_InitLicense(barcodeReader, "t0260NwAAAHV***************");DBR_SetTextResultCallback(barcodeReader, TextResultFunction, NULL);DBR_StartFrameDecoding(barcodeReader, 2, 10, 1024, 720, 720, IPF_BINARY, "");

How to Integrate C/C++ Thread-based APIs to Python Extension

Get the source code of Python barcode module built with Dynamsoft Barcode Reader 6.x.

Since the new APIs are thread-based, a callback function is required for returning the barcode results. Can we call Python function directly via C/C++ thread? No! Here is what you should do according to the Python online documentation:

The code snippet of calling Python function from the native thread is as follows:

Save a Python callback function and start a thread pool to process barcode detection events:

Append frames to a buffer queue:

Stop the thread pool:

Python Barcode Reader

Create a Python file without Python threading or multiprocessing modules:

Run the script. We can see the time cost of invoking appendVideoFrame() function can be ignored:

Dynamsoft Barcode Reader 7.0 is coming soon. If you are interested in the new version, stay tuned to Dynamsoft Barcode Reader homepage.

Source Code

https://github.com/dynamsoft-dbr/python/tree/7.x

Originally published at https://www.codepool.biz on July 7, 2019.

--

--

Xiao Ling
Xiao Ling

Written by Xiao Ling

Manager of Dynamsoft Open Source Projects | Tech Lover

No responses yet