Halcon基础学习笔记

关于Halcon

  • HALCON 的IDE有2种模式:HDevelop 和HDevelop XL。
    • hdevelop 适用于普通分辨率的图像,小于等于 32k x 32k;
    • hdevelop xl适用于大分辨率的图像,大于 32k x 32k 。
    • 每月公众号可以更新license,复制到lisence文件夹下面

常见参数

  • HDevelop采用的是面向过程的编程方式,所有的数据运算都可以通过算子来完成。

  • 常用的数据结构有两种:

    • 图形参数(Iconic)
      • Image(坐标的opencv的类似)
      • region
      • XLD
    • 控制参数(Control)
      • handle句柄
      • string
      • integer
      • real实数
      • Tuple数组
      • Dictionary字典
      • Vector向量
  • Image:

    • byte
    • byte+3通道
    • real(32位或者64位)
  • Region

    • 像素坐标点储存方式,以整型方式,类似游标编码,方便压缩和处理
  • XLD

    • 亚像素级别subpixel ,描述几何轮廓的对象

    • xld在模板匹配、图形校准等多方面有重要的用途

    • XLD有两种

      • Contours轮廓是一系列的点连接,点之间的距离大概是一个像素

      • polygons 多边形,点之间的距离较大,是用最少的线来描述这个轮廓

Region和XLD的常见操作

布尔操作

  • union1 union2:求并集
  • intersection:求交集
  • difference:求差集
  • complement:求补集
  • symm_difference:并集减去差集

Region/xld变换

  • gen_rectangle1 (Rectangle, 30, 20, 100, 200)

  • 形状转换

    • shape_trans (Rectangle, RegionTrans, 'convex')
  • 筛选

    • select_shape (RegionTrans, SelectedRegions1, 'area', 'and', 150, 99999)
  • 对于xld,上述在末尾加上_xld即可。

Region特征

圆度

矩形度

长度

紧密度

  • 圆的紧密度为1

凸性

刚体变换

  • 旋转矩阵和平移矩阵合二为一

  • 常用以下两个算子

    1
    2
    3
    4
    5
    
    //输入变换前后向量点和角度,返回刚体变换矩阵
    vector_angle_to_rigid (Exception, Exception, Exception, Exception, Exception, Exception, HomMat2D)
    
    //输入刚体变换矩阵和坐标点,输出变换后的坐标点,只是二维点    
    affine_trans_point_2d (HomMat2D, 64, 64, Qx, Qy)
    

仿射变换

常见算子hom_mat2d

坐标系避坑

  • 对于点,以(row,col)为表示,和上图的x、y不一样

向量角度避坑

angle_lx

  • 角度范围

  • 正负方向

line_orientation

  • Herror line_orientation(double RowBegin, double ColBegin, double RowEnd, double ColEnd, double* Phi)

  • 角度范围

Tuple数组

  • Tuple的常用语法

    • 我们常用的赋值语句a=0,在HDevelop中可以用分配函数assign (0, a)来完成,与之对应的表达式则可以写成a:=0,这里请大家注意 “:” 一定不能少哦。

    • 对于一些比较简单的算法,我们在书写表达式的时候可以直接将表达式中的“=”替换为 “:=”即可。Tuple支持我们常见的+、-、*、/、%等算数运算符,且每个运算符都有与其对应的函数。

  • Tuple看做C++语言中的数组来理解,不同的是Halcon里面固定只能是一维数组,但类型不固定。

    • 比如 a:=0

      • 可理解为 int* a=new int[1]; 也可理解为 a[0]=0;
    • 而 c:=a+b (a、b、c中都只有一个元素)

      • 可以理解为 c[0]=a[0]+b[0]
    • int* a=NULL,表示空数组。

      • 在HDevelop中,空数组这种情况可表示为a:=[]。我们可以通过type运算符或tuple_type函数判断a是否为空。该运算符返回a的数据类型,当a为空时返回31。31表示H_TYPE_ANY,为未知类型。
    •  1
       2
       3
       4
       5
       6
       7
       8
       9
      10
      
      a:=[]
      tuple_type(a,b)
      
      //或者
      a:=[]
      b:=type(a)
      
      //输出
      a=[]
      b=31
      
    • type类型

    • HALCON提供相应的数据类型判断函数
    1
    2
    3
    4
    5
    6
    7
    8
    
    is_int(t)
    is_real(t)
    is_number(t)
    is_mixed(t)
    is_string(t)
    type(t)
    sem_type(t)
    //例子
    

  • Tuple除了可以进行数据存储外,我们还可以对不同的数据类型进行运算,当然这其中也包括字符串。在数据与字符串运算时,会先将数据转换为字符串,然后进行字符串追加操作(如下面的f变量)。以下展示了几种典型的运算表达式及处理结果。

  • Tuple在数据的处理过程中,我们有时需要进行一些数组操作,如访问数组某个元素,删除或添加元素等等,下面我们就为大家演示,在HDevelop中如何实现这些操作。

    HDevelop表达式 功能 HALCON函数
    t:=[t1,t2] 在t1数组后追加t2数据并赋值给t tuple_contact
    i:=|t| 数组t的长度 tuple_length
    v:=t1[i] 从数组t1中取下标为i的值 tuple_select
    v:=t[i1:i2] 从数组t中选择i1到i2的元素 tuple_select_range
    t:=remove(t,i) 从数组t中删除下标为i的数据 tuple_remove
    i:=find(t1,t2) 从数组t1中搜索值为t2的数据,返回数据下标,未找到返回-1 tuple_find
    i:=find_first(t1,t2) 搜索t1中t2第一次出现的位置,未找到返回-1 tuple_find_first
    i:=find_last(t1,t2) 搜索t1中t2最后一次出现的位置,未找到返回-1 tuple_find_last
    t3:=replace(t1,i,t2) 替代数组t1中下标为i的数据为t2,返回替代结果为t3中 tuple_replace
    t:=sort(t1) 对数组t1升序排列并返回排列结果 tuple_sort
    t:=sort_index(t1) 对数组t1升序排序并返回排列后下标 tuple_sort_index
    t:=uniq(t) 如果数组中存在连续的相同的变量,则删除重复变量 tuple_uniq
    t:=[i1:i2:i3] 生成从i1到i3,步长为i2的数字序列 tuple_gen_sequence
    t:=[i1:i3] 生成从i1到i3,步长为1的数字序列 tuple_gen_sequence
    t:=gen_tuple_const(Num,n) 生成长度为Num,值为n的序列 tuple_gen_const

  • 使用HDevelop我们不仅能够实现数组的访问与修改,还可以进行一些集合运算,如求数据集的并集、交集、差集等。

    • 相关函数
    • 对称差:相对补集的并集

    • 示例

  • tuple逻辑运算——与或非

  • tuple位运算——左移、右移、按位与、或、异或
    • 二进制
    • a:=11(3)
    • 10(2)

  • tuple比较运算
    • 当我们对一个数组执行如下表中的比较运算时,只有数组的第一个元素参与了运算。

  • tuple比较运算2

    • 当我们对一个数组执行如下表中的比较运算时,数组的每一个元素(数组的每一项)都参与了运算。

  • tuple统计参数:除了对数组单个元素进行操作,我们还可以将计算数组作为样本进行相关的操作,如求样本的均值、中值、方差等。

​ 例子

1
2
3
4
5
6
7
8
a:=[3,1,2]
b:=[1,2,3]
c:=min2(a,b)
    
//输出
a:[3, 1, 2]
b:[1, 2, 3]
c:[1, 1, 2]
  • tuple一元函数:在HDevelop中还集成一些了我们常用的一元运算符,如绝对值、开方、取整、数据类型转换等。

  • tuple的字符串:在字符串操作方面HALCON也为我们提供了很多常用功能,包括字符串的转换、拼接、搜索等

  • 格式化输出:我们常用的格式输出如printf(“a=%d”,a),在HALCON中也可以实现,只是格式比较特殊,在HDevelop中格式化输出的运算符是$,该运算符的功效如下。

根据上表中的表达式以及输出结果我们不难看出:

①$前面可以为任意数据或变量,而​$后面的字符串表示了文本输出格式。其中f、x、d、s分别代表浮点型、16进制、整型以及字符串。

②一般小数点前面的数字表示生成字符串的长度,如果为正数则在文本小于此长度时字符串右对齐,如果为负数则左对齐。

③在小数点后面的数字,根据不同的转换方式,其含义各不相同。

-- 在整型转换中小数点后数字表示格式化输出整数位数,其中空位补0(第7行);

--在浮点型字符输出中表示保留小数位数(第3行);

--而在字符串转换中则表示字符截断数目(第10行)。

Vector向量

  • 和C++的vector容器不一样!

  • 在HALCON中有一种名为Vector向量的数据结构。通过它,我们可以存储多维的数据或图形,但图形和数据不能混合存储在同一个向量中。

  • 和Tuple不同的是

    • 可以存储多为数据或图形
    • 每一次类型单一,和数组不一样
  • 初始化

    向量用大括号表示,我们可以通过赋值语句对其进行初始化。

    • (1)生成一维向量

      va:={1,2,3} 或 va:={[1],[2],[3]}

    • (2)生成空向量

      va:={[]}

      va.clear()

    对于已生成的向量,在HDevelop代码编辑窗口中,我们可以查看到向量的相关操作:

  • 数据添加

    有两种方法可以为向量添加数据

    (1)追加

    (2)插入

  • 数据访问与赋值

    我们可以通过at方法对向量进行访问和赋值:

  • 向量嵌套与嵌套操作

    (1)向量嵌套

    在向量初始化时可以通过大括号的嵌套实现向量的嵌套,以此达到多维数据的存取。下图中的示例为大家展示了四维离散数据的向量结构存取。

​ (2)其实,在多维向量的访问中我们就已经用到了向量方法的嵌套操作

​ 其实,在多维向量的访问中我们就已经用到了向量方法的嵌套操作——例如va.at(0).at(0):=1。

​ 在向量自带的方法中at、insert以及remove是我们常用的可嵌套算法,他们既可以相互嵌套又可以和向量的其他算法配 合使用。下图中的示例就为我们演示了通过嵌套进行向量长度的获取以及数据的插入。

Halcon基础语法

  • 按tab键自动补全

  • halcon算子排列顺序

    • 输入:输出:控制输入:控制输出
    • 重点学习:算子+tuple
  •  1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    
    //赋值语句
    :=
    str:='strr'
    
    //tuple是一个灵活的数据类型可以使用string interger real boolean handle也可以是他们的数组,序号从0开始
    tuple1:=[]
    
    //控制语法操作
    //判断
    if(2>3)  
     	***
    else 
    	***
    elseif
    	***
    endif
    
    //循环执行1
    tuple1:=[]
    for Index := 0 to 5 by 1
        tuple1[Index]:=sqrt(Index)
    endfor
    
    //循环执行2
    m:=0
    while (m<3)
        m:=m+1
    endwhile
    
    //break和高级语言一样退出所有循环
    
    
    //continue和高级语言一样退出当前循环进入下一循环
    
    
    //switch
    a:=2
    switch (a)
    case 1:
        resule:=5
        break
    case 3:
        resule:=6
        break
    default:
        resule:='yrere'
    endswitch
    
    
    
    //错误处理try catch
    try
    
    catch (Exception)
    endtry