1,简介。
Halcon提供读取二维码格式类型为PDF417,数据矩阵ECC200、QR码,MicroQR码以及Aztec码。与条形码相似,均是对字符和数字进行编码,这些符号由暗条和亮条或成为模块的点组成。条形码使用黑色条和空格作为模块,由于单个暗条和亮条沿其高度具有恒定的宽度,因此可以沿符号的宽度在单个扫描线中读取条形码。与条形码相反,对于二维码符号,改变沿两个方向发生。因此相同的信息可以被编码到更小的符号中。符号的大小,由两个方向上的模块数量确定,以及编码信息的长度或者所读取信息所需要的纠错级别。后者需要可以完全解码的符号,即使符号具有小缺陷,比如,二维码中一些模块不可见模糊等。常见的两种不同类型的二维码为堆叠码与矩形码。
在堆叠码中,Halcon支持PDF417,其符号由几个条形码组成,这些条形码按照行和列进行排列,每一个条形码对单个“码字”进行编码。根据符号类型的名称,每个码字由四个暗条和四个光条(空格)构成的17个模块组合而成。它总是从黑暗开始,以光条结束。PDF417符号的行数和列数在3到90行、1到30列的范围内变化。开始和停止模式框定左右边框上的符号。码字的第一和最后列被称为左和右行指示符。在符号边界周围,放置均匀帧,这称为静区。对于小符号,存在PDF417的变体,其中没有右行指示符,停止模式减少为一个模块宽的条。它被称为紧凑或截断PDF417。
矩阵码使用的式图形模式,它主要由三部分组成:前景模块、背景模块和取景器。取景器用于查找符号在图像中的取向。Halcon支持的矩阵码为ECC200、QR、MicroQR、Aztec,如下图所示
对于矩阵码其前景和背景模块通常是正方形或矩形,但也出现圆形前景模块。模块按照行和列排序,行和列的数量定义符号的大小,对于QR码可以直接连接到其版本号,版本号越高,符号越大。ECC200的取景器为L型,以及在对应的边界上由暗和亮模块交替组成。QR码的取景器由三个“正方形”组成,称为“位置检测图形”。较小的MicroQR码只有1个取景器图形 ,也是正方形位于这个“位置检测图形”位于符号的左上角。Aztec码的取景器元素有嵌套在位于代码中间的方块组成。
尽管堆叠码也可以通过条形码读取器逐行读取,但是矩阵码只能通过检测图像来解码,即需要通过相机获取图像。每个二维码都可以使用不同格式的符号类型,只有在读取过程分配合适的参数,才能较好的实现对二维码符号内容的查找,解码。
2,参数解析。
2.1参数: 'default_parameters':
参数定义
用于配置二维码识别性能模式,默认值为 standard_recognition
,需在 create_data_code_2d_model
首位声明。
参数值 | 解码速度 | 识别精度 | 硬件资源占用 | 适用场景 |
---|---|---|---|---|
standard_recognition |
极快 (≤50ms) | 基础容错(破损率≤10%) | CPU < 30% | 常规印刷标签、流水线扫码 |
enhanced_recognition |
中等 (≤120ms) | 高精度(破损率≤25%) | CPU 50%-70% | 反光金属表面、轻微畸变 |
maximum_recognition |
慢 (≤300ms) | 极限容错(破损率≤40%) | GPU ≥80% | 强反光曲面、严重污损标签 |
* Initialize visual settings
dev_update_off ()
dev_close_window ()
dev_open_window (0, 0, 512, 512, 'black', WindowHandle)
set_display_font (WindowHandle, 14, 'mono', 'true', 'false')
dev_set_color ('green')
dev_set_line_width (3)
Message := 'This program demonstrates how to read 2d data'
Message[1] := 'codes with the following default settings:'
Message[2] := ' \'standard recognition\''
Message[3] := ' \'enhanced recognition\''
Message[4] := ' \'maximum recognition\''
Message[5] := ' '
Message[6] := 'Note that you can choose the desired symbol'
Message[7] := 'types by (un)commenting the corresponding'
Message[8] := 'lines in the code.'
disp_message (WindowHandle, Message, 'window', 12, 12, 'black', 'true')
disp_continue_message (WindowHandle, 'black', 'true')
stop ()
*
* Step 1: Choose the symbol type
* -------------------------------------------------------
* Choose the symbol types by (un)commenting the corresponding
* lines. Note that you can choose more than one symbol type.
SymbolType := []
SymbolType := [SymbolType,'QR Code']
SymbolType := [SymbolType,'Micro QR Code']
SymbolType := [SymbolType,'PDF417']
SymbolType := [SymbolType,'Aztec Code']
SymbolType := [SymbolType,'Data Matrix ECC 200']
*
* Loop over all chosen symbol types
* -------------------------------------------------------
* Get images of the chosen symbol types, create the
* corresponding data code model with each default setting,
* read the data codes with each model and display the results
for Index := 0 to |SymbolType| - 1 by 1
*
* Step 2 : Get image names for the current symbol type
* ----------------------------------------------------
* Ecc 200
if (SymbolType[Index] == 'Data Matrix ECC 200')
list_image_files ('datacode/ecc200', 'default', [], ImageFiles)
ImageFiles := regexp_select(ImageFiles,'(ecc200_cpu_)|(ecc200_disturbed_0)')
* QR Code
elseif (SymbolType[Index] == 'QR Code')
list_image_files ('datacode/qrcode', 'default', [], ImageFiles)
ImageFiles := regexp_select(ImageFiles,'qr_workpiece')
* Micro QR Code
elseif (SymbolType[Index] == 'Micro QR Code')
list_image_files ('datacode/micro_qr', 'default', [], ImageFiles)
ImageFiles := regexp_select(ImageFiles,'micro_qr')
* PDF417
elseif (SymbolType[Index] == 'PDF417')
list_image_files ('datacode/pdf417', 'default', [], ImageFiles)
ImageFiles := regexp_select(ImageFiles,'(pdf417_hd)|(pdf417_misc)')
* Aztec
elseif (SymbolType[Index] == 'Aztec Code')
list_image_files ('datacode/aztec', 'default', [], ImageFiles)
ImageFiles := regexp_select(ImageFiles,'aztec')
endif
*
* Step 3: Create data code models
* ---------------------------------------------------
* Create a model of the current symbol type for each
* default setting standard, enhanced, and maximum.
create_data_code_2d_model (SymbolType[Index], 'default_parameters', 'standard_recognition', DataCodeHandleStandard)
create_data_code_2d_model (SymbolType[Index], 'default_parameters', 'enhanced_recognition', DataCodeHandleEnhanced)
create_data_code_2d_model (SymbolType[Index], 'default_parameters', 'maximum_recognition', DataCodeHandleMaximum)
set_data_code_2d_param (DataCodeHandleMaximum, 'polarity', 'light_on_dark')
*
* Loop over all images
* ----------------------------------------------------
* Search and read the data codes in each image and
* display the decoded string for each found data code
NLoops := 20
for I := 0 to |ImageFiles| - 1 by 1
read_image (Image, ImageFiles[I])
dev_resize_window_fit_image (Image, 0, 0, -1, -1)
dev_display (Image)
*
* Step 4: Read the data codes
* -------------------------------------------
* Find and decode the data codes with each
* data code model and measure the runtime
*
* Standard mode
find_data_code_2d (Image, SymbolXLDs, DataCodeHandleStandard, [], [], ResultHandles, DecodedDataStrings)
count_seconds (T1)
for N := 1 to NLoops by 1
find_data_code_2d (Image, SymbolXLDs, DataCodeHandleStandard, [], [], ResultHandles, DecodedDataStrings)
endfor
count_seconds (T2)
FoundStandard := |DecodedDataStrings|
TimeStandard := 1000 * (T2 - T1) / real(NLoops)
*
* Enhanced mode
find_data_code_2d (Image, SymbolXLDs, DataCodeHandleEnhanced, [], [], ResultHandles, DecodedDataStrings)
count_seconds (T1)
for N := 1 to NLoops by 1
find_data_code_2d (Image, SymbolXLDs, DataCodeHandleEnhanced, [], [], ResultHan