2025-08-11 06:45:16Halcon算子 二维码识别、D、QR、ECC20、PDF417、QR Code,以及多线程读取

在Halcon中,二维码识别是一个常见的机器视觉任务,通常用于产品类型检测或MES系统对接。

Halcon提供冷一系列算子(operators)来简化二维码识别的过程。

操作步骤

读取二维码图像 read_image对图像进行想要预处理 【灰度化 二值化 区域特殊筛选 形态学 几何变换 区域锁定】创建二维码解析对象 create_data_code_2d_model设置解析对象相关的参数 set_data_code_2d_param搜索目标区域的二维码并解析获取解析结果 find_data_code_2d释放二维码解析对象 clear_data_code_2d_model

创建 create

设置 set

获取 get/query

搜索 find

生成 gen

绘制 draw

显示 dev_disp

预处理

图像预处理:对比度低或模糊,可以用 scale_image 和 emphasis二维码区域提取: 当图像信息过多,可以使用 reduce_domain 和 crop_domain算子,有助于降低解码难度并减少解码时间二维码放大:对于较小的二维码,可以用 zoom_image_factor 放大图像

案例

1.D码

*窗体清空,数据清空

dev_close_window ()

dev_update_off ()

*获取窗口句柄

dev_get_window (WindowHandle)

*设置字体

set_display_font (WindowHandle, 16, 'mono', 'true', 'false')

*ROI样式设置

dev_set_draw ('margin')

dev_set_color ('green')

dev_set_line_width (3)

*创建二维码格式

create_data_code_2d_model ('Data Matrix ECC 200', [], [], DataCodeHandle)

*设置二维码参数

set_data_code_2d_param (DataCodeHandle, 'default_parameters', 'maximum_recognition')

*读取文件夹

list_files ('D:/Halcon/‫Image/3二维D码', 'files', Files)

*正则表达式筛选

tuple_regexp_select (Files, '.(bmp|jpg)', Selection)

num:=|Selection|-1

for Index:=0 to num by 1

read_image (Image,Selection[Index])

*找到二维码

find_data_code_2d (Image, SymbolXLDs, DataCodeHandle, [], [], ResultHandles, DecodedDataStrings)

*获取结果

get_data_code_2d_results (DataCodeHandle, 'all_candidates', 'status', ResultValues)

*获取找到的数量

count_obj (SymbolXLDs, Number)

*显示

dev_display (Image)

dev_display (SymbolXLDs)

*显示解码结果

disp_message (WindowHandle, DecodedDataStrings, 'image', 12, 12, 'black', 'true')

if(Index==num)

disp_continue_message (WindowHandle, 'black', 'false')

else

disp_continue_message (WindowHandle, 'black', 'true')

stop ()

endif

endfor

disp_message (WindowHandle, '结束了', 'image', 200, 300, 'red', 'white')

2.QR码

*dev_update_off ()

*dev_close_window ()

dev_get_window (WindowHandle)

set_display_font (WindowHandle, 16, 'mono', 'true', 'false')

dev_set_draw ('margin')

dev_set_color ('green')

dev_set_line_width (3)

create_data_code_2d_model ('QR Code', 'default_parameters', 'maximum_recognition', DataCodeHandle)

list_files ('D:/Halcon/‫Image/4二维QR码', 'files', Files)

tuple_regexp_select (Files, '.(bmp|pg)', Selection)

for Index:=0 to |Selection|-1 by 1

read_image (Image, Selection[Index])

find_data_code_2d (Image, SymbolXLDs, DataCodeHandle, [], [], ResultHandles, DecodedDataStrings)

count_obj (SymbolXLDs, Number)

if(Number<1)

disp_message (WindowHandle, 'NG', 'window', 12, 12, 'red', 'true')

else

disp_message (WindowHandle, 'OK\r\n'+DecodedDataStrings, 'image', 12, 12, 'green', 'true')

endif

stop ()

endfor

disp_message (WindowHandle, '结束了', 'window', 200, 300, 'red', 'true')

3.中文QR解码

*将输入的参数从当前操作系统语言环境编码转换成UFT-8编码

set_system ('filename_encoding', 'utf8')

dev_update_off ()

dev_close_window ()

read_image (Image, 'D:/Halcon/‫Image/N维码/实现中文QR二维码的读取/1.png')

dev_open_window_fit_image (Image, 0, 0, -1, -1, WindowHandle)

set_display_font (WindowHandle, 16, 'mono', 'true', 'false')

dev_set_line_width (3)

dev_set_color ('green')

dev_display (Image)

create_data_code_2d_model ('QR Code', [], [], DataCodeHandle)

set_data_code_2d_param (DataCodeHandle, 'string_encoding', 'utf8')

find_data_code_2d (Image, SymbolXLDs, DataCodeHandle, [], [], ResultHandles, DecodedDataStrings)

dev_display (Image)

dev_display (SymbolXLDs)

disp_message (WindowHandle, '读出的二维码是'+DecodedDataStrings, 'window', 12, 12, 'black', 'true')

clear_data_code_2d_model (DataCodeHandle)

4.查找多维玛

dev_get_window (WindowHandle)

set_display_font (WindowHandle, 16, 'mono', 'true', 'false')

dev_set_color ('green')

dev_set_draw ('margin')

dev_set_line_width (3)

*创建 Data Matrix ECC 200二维码模板

create_data_code_2d_model ('Data Matrix ECC 200', 'default_parameters', 'maximum_recognition', DataCodeHandleECC200)

*创建PDF417二维码模板

create_data_code_2d_model ('PDF417', 'default_parameters', 'maximum_recognition', DataCodeHandlePDF417)

*创建QR Code二维码模板

create_data_code_2d_model ('QR Code', 'default_parameters', 'maximum_recognition', DataCodeHandleQR)

list_files ('D:/Halcon/‫Image/N维码/兼容多种二维码读取案例', 'files', Files)

tuple_regexp_select (Files, '.(jpg|bmp|png)', Selection)

for Index:=0 to |Selection|-1 by 1

read_image (Image, Selection[Index])

find_data_code_2d (Image, SymbolXLDs, DataCodeHandleECC200, [], [], ResultHandles, DecodedDataStrings)

count_obj (SymbolXLDs, Number)

if(Number>0)

disp_message (WindowHandle, '发现ECC200码:\n\r'+DecodedDataStrings, 'window', 12, 12, 'black', 'true')

disp_continue_message (WindowHandle, 'black', 'true')

stop ()

else

find_data_code_2d (Image, SymbolXLDs, DataCodeHandlePDF417, [], [], ResultHandles1, DecodedDataStrings)

count_obj (SymbolXLDs, Number)

if(Number>0)

disp_message (WindowHandle, '发现PDF417码:\n\r'+DecodedDataStrings, 'window', 12, 12, 'black', 'true')

disp_continue_message (WindowHandle, 'black', 'true')

stop ()

else

find_data_code_2d (Image, SymbolXLDs, DataCodeHandleQR, [], [], ResultHandles1, DecodedDataStrings)

count_obj (SymbolXLDs, Number)

if(Number>0)

disp_message (WindowHandle, '发现QR码:\n\r'+DecodedDataStrings, 'window', 12, 12, 'black', 'true')

disp_continue_message (WindowHandle, 'black', 'true')

stop ()

else

disp_message (WindowHandle, '未发现二维码', 'window', 12, 12, 'black', 'true')

disp_continue_message (WindowHandle, 'black', 'true')

stop ()

endif

endif

endif

endfor

disp_message (WindowHandle, '结束了', 'window', 200, 300, 'black', 'true')

clear_data_code_2d_model (DataCodeHandleQR)

clear_data_code_2d_model (DataCodeHandlePDF417)

clear_data_code_2d_model (DataCodeHandleECC200)

5.ECC 200 实例

create_data_code_2d_model ('Data Matrix ECC 200', 'default_parameters', 'maximum_recognition', DataCodeHandle)

dev_get_window (WindowHandle)

dev_set_color ('green')

dev_set_draw ('margin')

dev_set_line_width (3)

set_display_font (WindowHandle, 16, 'mono', 'true', 'false')

list_files ('D:/Halcon/‫Image/二维码教程/ecc 200检测实例', 'files', Files)

tuple_regexp_select (Files, '.(jpg|png|bmp|tif)', Selection)

for Index:=0 to |Selection|-1 by 1

read_image (Image, Selection[Index])

get_image_size (Image, Width, Height)

zoom_image_factor (Image, Image, 0.15, 0.15, 'constant')

find_data_code_2d (Image, SymbolXLDs, DataCodeHandle, [], [], ResultHandles, DecodedDataStrings)

count_obj (SymbolXLDs, Number)

if(Number<1)

stop()

find_data_code_2d (Image, SymbolXLDs, DataCodeHandle, 'train', 'all', ResultHandles, DecodedDataStrings)

count_obj (SymbolXLDs, Number)

endif

count_obj (SymbolXLDs, Number)

if(Number>0)

disp_message (WindowHandle, 'OK\r\n'+DecodedDataStrings, 'window', 12, 12, 'black', 'true')

else

disp_message (WindowHandle, 'NG', 'window', 12, 12, 'black', 'true')

endif

stop ()

endfor

disp_message (WindowHandle, '结束了', 'window', 200, 300, 'black', 'true')

clear_data_code_2d_model (DataCodeHandle)

6.PDF417 码

dev_close_window ()

dev_set_draw ('margin')

dev_set_color ('green')

dev_set_line_width (3)

dev_get_window (WindowHandle1)

set_display_font (WindowHandle1, 16, 'mono', 'true', 'false')

dev_get_window (WindowHandle)

create_data_code_2d_model ('PDF417', 'default_parameters', 'maximum_recognition', DataCodeHandle)

list_files ('D:/Halcon/‫Image/二维码教程/pdf417', 'files', Files)

tuple_regexp_select (Files, '.(png|jpg|bmp)', Selection)

for i:=0 to |Selection|-1 by 1

read_image (Image, Selection[i])

find_data_code_2d (Image, SymbolXLDs, DataCodeHandle, [], [], ResultHandles, DecodedDataStrings)

count_obj (SymbolXLDs, Number)

if(Number<1)

*训练模板。训练模板的时间比较长,比正常识别长很多,而且当训练模板没有找到二维码的时候,时间会更长

find_data_code_2d (Image, SymbolXLDs1, DataCodeHandle, 'train', 'all', ResultHandles1, DecodedDataStrings1)

*为了防止程序崩溃,导致保存添加了新信息的模板丢失,及时保存新模板

write_data_code_2d_model (DataCodeHandle, 'C:/Users/86195/Desktop/二维码集合/data_code_model.dcm')

stop ()

endif

count_obj (SymbolXLDs, Number)

if(Number<1)

disp_message (WindowHandle, 'NG', 'window', 12, 12, 'black', 'true')

else

disp_message (WindowHandle, 'OK\r\n'+DecodedDataStrings, 'window', 12, 12, 'black', 'true')

endif

stop ()

endfor

disp_message (WindowHandle, '结束了', 'window', 200, 300, 'black', 'true')

clear_data_code_2d_model (DataCodeHandle)

7.QR Code 码

dev_close_window ()

dev_get_window (WindowHandle)

dev_set_draw ('margin')

dev_set_color ('green')

dev_set_line_width (3)

set_display_font (WindowHandle, 16, 'mono', 'true', 'false')

create_data_code_2d_model ('QR Code', 'default_parameters', 'maximum_recognition', DataCodeHandle)

list_files ('D:/Halcon/‫Image/二维码教程/qrcode', 'files', Files)

tuple_regexp_select (Files, '.(jpg|bmp|png)', Selection)

for i:=0 to |Selection|-1 by 1

read_image (Image, Selection[i])

find_data_code_2d (Image, SymbolXLDs, DataCodeHandle, [], [], ResultHandles, DecodedDataStrings)

count_obj (SymbolXLDs, Number)

if(Number<1)

find_data_code_2d (Image, SymbolXLDs1, DataCodeHandle, 'train', 'all', ResultHandles1, DecodedDataStrings1)

write_data_code_2d_model (DataCodeHandle, 'C:/Users/86195/Desktop/二维码集合/data_code_model.dcm')

stop ()

endif

count_obj (SymbolXLDs, Number)

if(Number<1)

disp_message (WindowHandle, DecodedDataStrings, 'window', 12, 12, 'black', 'true')

else

disp_message (WindowHandle, 'OK\r\n'+DecodedDataStrings, 'window', 12, 12, 'black', 'true')

endif

stop ()

endfor

disp_message (WindowHandle, '结束了', 'window', 200, 300, 'black', 'true')

clear_data_code_2d_model (DataCodeHandle)

8.多线程并行读取QR码

**************************************************************************1.初始化****************************************************

*测量次数

Loops := 3

*关闭程序计数器,图形窗口更新,图像变量更新

dev_update_off ()

*关闭已经打开的窗口

dev_close_window ()

*读取一张图像

read_image (Image, 'barcode/mixed/barcodes_datacodes_mixed_01')

*创建一个窗口,图像可以自适应该窗口

dev_open_window_fit_image (Image, 0, 0, -1, -1, WindowHandle)

*设置字体显示信息:字体大小:16;字体类型:mono;粗体,斜体;

set_display_font (WindowHandle, 16, 'mono', 'true', 'false')

*显示图像

dev_display (Image)

**************************************************************************1.多线程来对多个二维码进行解码****************************************************

*创建一个QR Code类型的二维码模版

create_data_code_2d_model ('QR Code', [], [], QrCodeModel)

*创建一个Data Matrix ECC 200类型的二维码模版

create_data_code_2d_model ('Data Matrix ECC 200', 'default_parameters', 'maximum_recognition', Ecc200Model)

*创建一个一维码模版

create_bar_code_model ([], [], BarCodeModel)

* 训练Qr二维码模版

find_data_code_2d (Image, QrCodeXldsSeq, QrCodeModel, ['stop_after_result_num','train'], [2,'all'], QrCodeHandlesSeq, QrCodeStringsSeq)

* 训练Ecc200二维码模版

find_data_code_2d (Image, Ecc200XldsSeq, Ecc200Model, ['stop_after_result_num','train'], [2,'all'], Ecc200HandlesSeq, Ecc200StringsSeq)

* 训练EAN-13一维码模版

find_bar_code (Image, BarCodeRegionsSeq, BarCodeModel, ['EAN-13','Code 128'], BarCodeStringsSeq)

* 串行识别二维码信息,循环识别3次

count_seconds (T1)

for L := 1 to Loops by 1

find_qr_codes (Image, QrCodeXldsSeq, QrCodeModel, QrCodeHandlesSeq, QrCodeStringsSeq)

find_ecc200_codes (Image, Ecc200Xlds, Ecc200Model, Ecc200Handles, Ecc200Strings)

find_bar_codes (Image, BarCodeRegions, BarCodeModel, BarCodeStrings)

endfor

count_seconds (T2)

*串行操作花费的时间

TimeSeq := 1000.0 * (T2 - T1) / Loops

* 并行识别二维码信息,循环识别3次

count_seconds (T1)

for L := 1 to Loops by 1

*** 开启多线程 par_start<线程名称>

par_start : find_qr_codes (Image, QrCodeXlds, QrCodeModel, QrCodeHandlesSeq, QrCodeStringsSeq)

par_start : find_ecc200_codes (Image, Ecc200Xlds, Ecc200Model, Ecc200Handles, Ecc200Strings)

par_start : find_bar_codes (Image, BarCodeRegions, BarCodeModel, BarCodeStrings)

* 等待3个线程执行完成

par_join ([ThreadQRCode,ThreadECC200,ThreadBarcode])

endfor

count_seconds (T2)

*并行操作花费的时间

TimePar := 1000.0 * (T2 - T1) / Loops

* 计算并行相对串行速度提升了多少

Speedup := 100 * ((TimeSeq / TimePar) - 1)

* 显示识别到的二维码区域

dev_set_draw ('margin')

dev_set_line_width (4)

dev_set_color ('yellow')

dev_display (QrCodeXlds)

dev_set_color ('green')

dev_display (Ecc200Xlds)

dev_set_color ('cyan')

dev_display (BarCodeRegions)

Color := ['forest green','red']

disp_message (WindowHandle, 'Multithreading speedup: ' + Speedup$'.2f' + '%', 'window', 42, 12, Color[Speedup < 1], 'true')

*删除各自条码模版并释放分配内存

clear_bar_code_model (BarCodeModel)

clear_data_code_2d_model (Ecc200Model)

clear_data_code_2d_model (QrCodeModel)