The Hidden Image Data of Dynamsoft Barcode SDK You Don’t Know

While scanning single or multiple barcodes with a barcode SDK, most of the developers only concern about the trade-off between decoding speed and recognition accuracy, for they cannot get other data. Since from version 8.0, Dynamsoft exposes more parameters and intermediate results (E.g., grayscale image, binary image, barcode localization results, etc.) to developers for app debugging and optimizing, which makes Dynamsoft Barcode SDK stand out from commercial barcode SDKs. In this article, I will go through some relevant parameters and APIs.

Requirements

  • CMake
  • OpenCV 4.5.0. For Windows, you need to add “OpenCV_DIR = C:\opencv\build” to system environment variables.

Linking OpenCV and Dynamsoft Barcode SDK in CMake Project

If you have successfully installed OpenCV, linking OpenCV libraries is quite simple:

find_package(OpenCV REQUIRED)
if (CMAKE_HOST_WIN32)
 if (CMAKE_CL_64)
 	target_link_libraries (BarcodeReaderDemo "DBRx64" ${OpenCV_LIBS})
 else ()
 	target_link_libraries (BarcodeReaderDemo "DBRx86" ${OpenCV_LIBS})
 endif()
else ()
	target_link_libraries (BarcodeReaderDemo "DynamsoftBarcodeReader" ${OpenCV_LIBS})
endif()

As for Dynamsoft Barcode SDK, the link directories are set manually:

if (CMAKE_HOST_WIN32)
 if (CMAKE_CL_64)
 	link_directories("${PROJECT_SOURCE_DIR}/lib/Windows/x64")
 else()
 	link_directories("${PROJECT_SOURCE_DIR}/lib/Windows/x86")
 endif()
else if(CMAKE_HOST_UNIX)
 link_directories("${PROJECT_SOURCE_DIR}/lib/Linux")
endif()

Getting Transformed Images and Predicted Barcode Bounding Boxes

Let’s look under the hood to see how Dynamsoft barcode reader works.

The general way of scanning barcodes with Dynamsoft Barcode Reader is as follows:

CBarcodeReader reader;
ret = reader.InitLicense("LICENSE-KEY");
ret = reader.DecodeFile(imageFile, templateName);
TextResultArray *finalResults = NULL;
reader.GetAllTextResults(&finalResults);
for (int index = 0; index < finalResults->resultsCount; index++)
{
  printf("Value: %s\r\n", finalResults->results[index]->barcodeText);
}

As a matter of fact, you can get more than just the final results. All transformed image data generated during the barcode decoding process can be saved for further use.

There are some enumeration types defined in the DynamsoftBarcodeReader.h header file:

typedef enum IntermediateResultType
{ 
 /**No intermediate result */
 IRT_NO_RESULT = 0x00000000,

 /**Original image */
 IRT_ORIGINAL_IMAGE = 0x00000001,

 /**Colour clustered image. Not supported yet. */
 IRT_COLOUR_CLUSTERED_IMAGE = 0x00000002,

 /**Colour image converted to grayscale  */
 IRT_COLOUR_CONVERTED_GRAYSCALE_IMAGE = 0x00000004,

 /**Transformed grayscale image */
 IRT_TRANSFORMED_GRAYSCALE_IMAGE = 0x00000008,

 /**Predetected region */
 IRT_PREDETECTED_REGION = 0x00000010,

 /**Preprocessed image */
 IRT_PREPROCESSED_IMAGE = 0x00000020,

 /**Binarized image */
 IRT_BINARIZED_IMAGE = 0x00000040,

 /**Text zone */
 IRT_TEXT_ZONE = 0x00000080,

 /**Contour */
 IRT_CONTOUR = 0x00000100,

 /**Line segment */
 IRT_LINE_SEGMENT = 0x00000200,

 /**Form. Not supported yet. */
 IRT_FORM = 0x00000400,

 /**Segmentation block. Not supported yet. */
 IRT_SEGMENTATION_BLOCK = 0x00000800,

 /**Typed barcode zone */
 IRT_TYPED_BARCODE_ZONE = 0x00001000,

 /**Predetected quadrilateral*/
 IRT_PREDETECTED_QUADRILATERAL = 0x00002000

}IntermediateResultType;

According to the definitions, it is easy to infer what image processing algorithms that Dynamsoft has adopted. Now, I write some code snippets to demonstrate how to get grayscale image, binary image and barcode bounding boxes.

Before decoding barcode images, configure the intermediate data you want to acquire:

reader.GetRuntimeSettings(&amp;runtimeSettings);
runtimeSettings.barcodeFormatIds = barcodeFormat.barcodeFormatIds;
runtimeSettings.barcodeFormatIds_2 = barcodeFormat.barcodeFormatIds_2;
runtimeSettings.intermediateResultSavingMode = IRSM_MEMORY;
runtimeSettings.intermediateResultTypes = IRT_BINARIZED_IMAGE | IRT_TRANSFORMED_GRAYSCALE_IMAGE | IRT_TYPED_BARCODE_ZONE;
runtimeSettings.scaleDownThreshold = 10000;
ret = reader.UpdateRuntimeSettings(&amp;runtimeSettings, errorMSG, 256);

By default, the saving mode is IRSM_MEMORY. If you want to save data to file system, you can change it to IRSM_FILESYSTEM. The scaleDownThreshold is used to control the input image size. If the width of your input image is larger than the threshold, the image will be scaled down.

After calling a decoding method, we can invoke GetIntermediateResults() to get a list of mixed data:

IntermediateResultArray* intermediateResults = NULL;

reader.GetIntermediateResults(&amp;intermediateResults);

for (int i = 0; i < intermediateResults->resultsCount; i++)

{

}

If the data type is IMRDT_IMAGE, you can get an image buffer:

if(intermediateResults->results[i]->dataType == IMRDT_IMAGE)
{
 int type = 0;
 ImageData* imageData = (ImageData*)intermediateResults->results[i]->results[0];
 switch(imageData->format)
 {
 case IPF_BINARY:
 case IPF_GRAYSCALED:
 case IPF_BINARYINVERTED:
 	type = CV_8UC1;
 	break;
 case IPF_RGB_888:
 	type = CV_8UC3;
 	break;
 default:
 	break;
 }
}

If the data type is IMRDT_LOCALIZATIONRESULT, you can get barcode bounding boxes:

if (intermediateResults->results[i]->dataType == IMRDT_LOCALIZATIONRESULT
{
 LocalizationResult *pLocalizationResult = (LocalizationResult *)intermediateResults->results[i]->results[0];
 int x1 = pLocalizationResult->x1;
 int y1 = pLocalizationResult->y1;
 int x2 = pLocalizationResult->x2;
 int y2 = pLocalizationResult->y2;
 int x3 = pLocalizationResult->x3;
 int y3 = pLocalizationResult->y3;
 int x4 = pLocalizationResult->x4;
 int y4 = pLocalizationResult->y4;
}

We use OpenCV imshow() function to display the transformed images and barcode bounding boxes.

Grayscale Image

multi barcode grayscale image

Binary Image

binary image

Barcode Bounding Box

barcode bounding box

You can write your code to explore more intermediate data generated by Dynamsoft Barcode SDK.

References

Source Code

https://github.com/Dynamsoft/barcode-intermediate-results

Search Blog Posts