• region、xld有对应的字符串时,将region、xld按照行或列排序的算法实现


    用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'这四种排序规则的区别。

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

  • 相关阅读:
    mysql命令集锦
    linux 删除文件名带括号的文件
    linux下的cron定时任务
    struts2文件下载的实现
    贴一贴自己写的文件监控代码python
    Service Unavailable on IIS6 Win2003 x64
    'style.cssText' is null or not an object
    "the current fsmo could not be contacted" when change rid role
    远程激活程序
    新浪图片病毒
  • 原文地址:https://www.cnblogs.com/xh6300/p/11913218.html
Copyright © 2020-2023  润新知