从8.0版开始,Dynamsoft向开发人员公开更多参数和中间结果(例如,灰度图像,二进制图像,条形码定位结果等),以进行应用程序调试和优化,从而使Dynamsoft Barcode SDK在商业条形码SDK中脱颖而出。在本文中,我将介绍一些相关的参数和API。

Dynamsoft Barcode Reader SDK一款多功能的条码读取控件,只需要几行代码就可以将条码读取功能嵌入到Web或桌面应用程序。这可以节省数月的开发时间和成本。能支持多种图像文件格式以及从摄像机或扫描仪获取的DIB格式。使用Dynamsoft Barcode Reader SDK,你可以创建强大且实用的条形码扫描仪软件,以满足你的业务需求。

【慧都网】下载Dynamsoft Barcode Reader最新版

在使用条形码SDK扫描单个或多个条形码时,大多数开发人员只关心解码速度和识别精度之间的权衡,因为他们无法获取其他数据。从8.0版开始,Dynamsoft向开发人员公开更多参数和中间结果(例如,灰度图像,二进制图像,条形码定位结果等),以进行应用程序调试和优化,从而使Dynamsoft Barcode SDK在商业条形码SDK中脱颖而出。在本文中,我将介绍一些相关的参数和API。

要求

CMake
OpenCV 4.5.0版。对于Windows,您需要OpenCV_DIR = C:\opencv\build在系统环境变量中添加“ ”。

Java使用opencv进行条形码定位矫正和裁剪_OpenCV

Dynamsoft条码阅读器8.0。要解锁所有功能,您必须申请试用许可证。

在CMake项目中链接OpenCV和Dynamsoft Barcode SDK

如果您已经成功安装了OpenCV,则链接OpenCV库非常简单:

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()

对于Dynamsoft Barcode SDK,链接目录是手动设置的:

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()

获取转换后的图像和预测的条形码边界框

让我们来看一下Dynamsoft条码读取器的工作原理。

使用Dynamsoft条码读取器扫描条码的一般方法如下:

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);
}

Java使用opencv进行条形码定位矫正和裁剪_灰度图像_02

事实上,您可以获得的不仅仅是最终结果。条形码解码过程中生成的所有转换图像数据都可以保存以备将来使用。

DynamsoftBarcodeReader.h头文件中定义了一些枚举类型:

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;

根据定义,很容易推断Dynamsoft采用了哪些图像处理算法。现在,我写一些代码片段来演示如何获取灰度图像,二进制图像和条形码边界框。
在解码条形码图像之前,请配置要获取的中间数据:

reader.GetRuntimeSettings(&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(&runtimeSettings, errorMSG, 256);

默认情况下,保存模式为IRSM_MEMORY。如果要将数据保存到文件系统,可以将其更改为IRSM_FILESYSTEM。所述scaleDownThreshold用于控制输入图像尺寸。如果输入图像的宽度大于阈值,则图像将按比例缩小。

调用解码方法后,我们可以调用GetIntermediateResults()以获得混合数据列表:

IntermediateResultArray* intermediateResults = NULL;
reader.GetIntermediateResults(&intermediateResults);
for (int i = 0; i < intermediateResults->resultsCount; i++)
{
}

如果数据类型为IMRDT_IMAGE,则可以获取图像缓冲区:

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;
 }
}

如果数据类型为IMRDT_LOCALIZATIONRESULT,则可以获得条形码边界框:

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;
}

我们使用OpenCV imshow()函数显示转换后的图像和条形码边界框。

灰度图像

Java使用opencv进行条形码定位矫正和裁剪_灰度图像_03

二进制图像

Java使用opencv进行条形码定位矫正和裁剪_灰度图像_04

条码边界框

Java使用opencv进行条形码定位矫正和裁剪_OpenCV_05

您可以编写代码来探索Dynamsoft Barcode SDK生成的更多中间数据。