用Halcon解码时,如果一张图里面有多个码,它通常可以把这些码都解出来,并且生成对应的解码结果字符串元组(也就是下面的DecodedDataStrings),如果有多个码,那么该元组就有多个元素。

① find_bar_code(Image : SymbolRegions : BarCodeHandle, CodeType : DecodedDataStrings)

② find_data_code_2d(Image : SymbolXLDs : DataCodeHandle, GenParamName, GenParamValue : ResultHandles, DecodedDataStrings)

 

一维码和二维码解码的区别是:一维码解码后的显示区域是一个region(SymbolRegions ),而二维码解码后的显示区域是一个xld(SymbolXLDs )

 

码的显示区域和解码字符串是一一对应的。但是有多个码时,不同码的显示区域顺序本身是乱排的,并不是按照“行坐标”或者“列坐标”排序的。如何让它们有序排列,并且字符串和它们的对应关系不变呢?这篇文章即是为了解决这个问题。

 

先了解一个排序算子:tuple_sort_index( : : Tuple : Indices)

基本上,Halcon中绝大多数的排序问题,都需要用到这个算子。关于这个算子的理解,详见我之前的文章:Halcon选择一堆region中面积第N大的region的算法实现

 

排序算法设计分析:

① 需排序的数据对假设是(region1, string1)、(region2, string2)、(region3, string3)、(region4, string4)……

② 以一维码、二维码以及它们对应的字符串为例,一维码解码显示区域是region,二维码解码显示区域是xld,所以该排序函数要兼容region和xld两种图形格式。

③ 为简单起见,均只设计为从小到大排序。设计了四种排序规则,分别是'row1'(最小外接矩形左上角行坐标)、'row'(中心点行坐标)、'column1'(最小外接矩形左上角列坐标)、'column'(中心点列坐标)

 

封装的函数签名为:sort_objects_strings(SourceObjects : SortedObjects : SourceStrings, ObjectType, SortRule : SortedStrings)

sort_objects_strings函数代码为:

 1 tuple_regexp_replace (ObjectType, ['\\s*','replace_all'], '', ObjectType) 
 2 tuple_regexp_replace (SortRule, ['\\s*','replace_all'], '', SortRule) 
 3 
 4 
 5 *是region还是xld
 6 if (ObjectType == 'region')
 7     ObjectType := 'region'
 8 else 
 9     ObjectType := 'xld'           
10 endif
11 
12 
13 *如果SourceStrings为空,或者SourceObjects和SourceStrings个数不同,这些都属异常,需return()
14 count_obj (SourceObjects, Num)
15 if (|SourceStrings| ==0 or |SourceStrings| != Num)
16     SortedObjects := SourceObjects
17     SortedStrings := SourceStrings
18     return ()
19 endif
20     
21 
22 *逻辑判断(如果是region)
23 if (ObjectType  == 'region')
24     *row1  row  column1  column, 看按哪种规则排序(下同)
25     if (SortRule == 'row1')
26         smallest_rectangle1 (SourceObjects, SortItems, Column1, Row2, Column2)
27     elseif(SortRule == 'column1')
28         smallest_rectangle1 (SourceObjects, Row1, SortItems, Row2, Column2)
29         
30     elseif(SortRule == 'row')
31         area_center (SourceObjects, Area, SortItems, Column)   
32     else
33         area_center (SourceObjects, Area, Row, SortItems)
34     endif
35 
36 *逻辑判断(如果是xld)
37 else
38     if (SortRule == 'row1')
39         smallest_rectangle1_xld (SourceObjects, SortItems, Column1, Row2, Column2)
40     elseif(SortRule == 'column1')
41         smallest_rectangle1_xld (SourceObjects, Row1, SortItems, Row2, Column2)
42         
43     elseif(SortRule == 'row')
44         area_center_xld (SourceObjects, Area, SortItems, Column, PointOrder)          
45     else
46         area_center_xld (SourceObjects, Area, Row, SortItems, PointOrder)
47     endif
48     
49 endif
50     
51 
52 * sort_region (SourceObjects, SortedObjects, 'upper_left', 'true', 'row')
53 * sort_contours_xld (SourceObjects, SortedObjects, 'upper_left', 'true', 'row')
54 
55 tuple_sort_index (SortItems, Indices)
56 
57 *SourceStrings和SourceObjects的排序
58 SortedStrings := []
59 gen_empty_obj (SortedObjects)
60 for i := 0 to Num-1 by 1
61     SortedStrings[i] := SourceStrings[Indices[i]]
62     select_obj (SourceObjects, ObjectSelected, Indices[i] + 1)
63     concat_obj (SortedObjects, ObjectSelected, SortedObjects)
64 endfor
65 
66 return ()

 

 

【示例】

 

程序是用Halcon 17.12写的,如果是低版本Halcon,那么文本显示和字体设置的语句略有不同。

 

 1 dev_set_draw ('margin')
 2 dev_set_line_width (3)
 3 set_display_font (200000, 22, 'Courier', 'true', 'false')
 4 
 5 read_image (Image, 'SortCodes')    
 6 create_data_code_2d_model ('QR Code', 'default_parameters', 'enhanced_recognition', DataCodeHandleQR) 
 7 
 8 *'stop_after_result_num', 10:意思是最大可找到10个码,如果不设置该参数,那么只会找到一个码
 9 find_data_code_2d (Image, SymbolXLDs, DataCodeHandleQR, 'stop_after_result_num', 10, ResultHandles, SourceStrings)
10 sort_objects_strings (SymbolXLDs, SymbolXLDsSort, SourceStrings, 'xld', 'row1', SortedStrings)
11 
12 dev_display (Image)
13 for Index := 0 to |SourceStrings|-1 by 1
14     select_obj (SymbolXLDsSort, ObjectSelected, Index + 1)   
15     dev_display (ObjectSelected)
16     area_center_xld (ObjectSelected, Area, Row, Column, PointOrder)
17     disp_message (200000, (Index + 1) + '' + SortedStrings[Index], 'image', Row, Column-50, 'black', 'true')
18 endfor
19 
20 clear_data_code_2d_model (DataCodeHandleQR)

 

① 按'row1'规格排序,效果图为:

 

 

② 按'row'规格排序,效果图为:

 

 

③ 按'column1'规格排序,效果图为:

 

 

④ 按'column'规格排序,效果图为:

 

请读者朋友们自己观察一下这四种效果图,体会一下'row1'、'row'、'column1'、'column'这四种排序规则的区别。

 

值得说明的是:这种排序算法是通用的,它不仅仅局限解码项目中的数据处理,其他类似的排序需求,也是可以用的。

 

posted on 2019-11-22 18:12  xh6300  阅读(1154)  评论(4编辑  收藏  举报