halcon基础学习(1)—软件安装以及基本语法

(一)软件安装

halcon 在工业机器视觉中占得比重很大,当然这是在传统机器视觉中的位置,作为商用软件自然是做得很好的,下面链接的为17.12 破解版本,只为学习交流,其他用途与我无关,哈哈。安装教程我就不罗嗦,初步的菜单,工具自己看吧,通用软件的结构
链接:https://pan.baidu.com/s/1V48jyOMCB201PizogYQ77w
提取码:NiuB
halcon基础学习(1)—软件安装以及基本语法_第1张图片
最主要的窗口:
1、图形窗口,2变量窗口,3算子窗口,4程序创库(我用的是18.11版本)

(二)基本语法

其实halcon算是有自己的语法,在实际编程中我们都是通过它自有的工具生成部分代码,所以算子也好,具体语法也好也不用可以去记,项目做多了就知道,halcon作为传统视觉处理的大致思路都差不多(一、图像采集,二、图像分割,三、形态学处理,四、特征提取,五、输出结果。),所以算子也可以归为几类,另外官方给的例子也是最权威的,可以多看。下面只总结基础的语法,作为参考。

2.1、语法结构特点

类似于Pascal 与 Visual Basic,大部分的语句是Halcon提供的算子,此外也包含了少部分的控制语句;
(1)不允许单独声明变量;
(2)提供自动的内存管理(初始化、析构及OverWrite),但句柄则需要显示释放

C++(算子模式)
通过代码导出,以C++为例,默认导出为算子型的语法结构,而非面向对象的;在此模式下,全部函数声明为全局类型,数据类型只需要用Hobject、HTuple两类类型进行声明;

C++(面向对象)
可以以面向对象的方式重写代码,也即利用类及类的成员函数;
在这种模式下,控制变量的类型仍未HTuple,而图形数据可以由多种类型,如HImage等;

其他语言(略)
HImage 可以查看halcon中类相关的内容

2.2 主要参数类型

两类参数:
1、图形参数Iconic (image, region, XLD)
2、与控制参数Control (string, integer, real, handle),
在Halcon算子的参数中,依次为:输入图形参数、输出图形参数、输入控制参数、输出控制参数;并且其输入参数不会被算子改变

2.2.1、图形参数Iconic:

(1)Images

在Halcon中,Image = Channel + Domain , 像素点存放在Channel矩阵中,根据ROI来描述Image。
Image相关操作:
输入:从文件、从设备
生成:外部图像数据、空内存区域;
显示:disp_image()图像首通道灰度图;disp_color() 彩色图;disp_channel()某特定通道;disp_obj() 自动判别类别;
缩放:set_part() 设置显示区域;set_part_style() 设置显示参数;

(2)Regions

以行列坐标形式储存,有广泛的应用,特点是高效,可利用同态算子。比如用阈值对图像分割的结果,其他系统中称为BOLB,AREA等

(3)Extended Line Description (XLD)

图像均用像素点保存,而像素点是整型的,不连续的,Halcon做了拓展,定义了亚像素(subpixel)的描述几何轮廓的对象:xld,主要用在亚像素测量的背景下,可用于如提取边缘、构建轮廓等等,xld在模板匹配、图形校准等多方面有重要的用途。

说明:
Subpixel accurate line and edge detection(亚像素精度的线和边缘检测)
Generic point list based data structure(依据数据结构产生点的表)
Handling of contours, polygons, lines, parallels, etc.(对轮廓,多边形,线等进行操作)

2.2.2、控制参数Control:

String类型变量由单引号’括起来;此外还有一些特殊字符;
Boolean型变量包括 true ( = 1 )、 false ( = 0 ) ;不为零的整数将被认为true;但绝大多数的Halcon函数接受字符串型的表达:’true’‘false’,而非逻辑型表达;
此外,Halcon支持的类型还包括图形元组、控制变量元组及句柄:
元组的概念,使得可以用一个变量传递数个对象,可以由重载后的函数来进行处理;图形元组的下标从1开始,控制变量元组下标从0开始;句柄则可以用来描述窗体、文件等等,句柄不能是常量。

2.3 Halcon的基本语句

1、标准赋值
Ø assign(Input, Result) //编辑形式,永远都是输入在前,输出在后
1: assign(sin(x) + cos(y), u)
Ø Result := Input //代码形式
1: u := sin(x) + cos(y) //与之前的assign(sin(x) + cos(y), u)是等价的
2、元组插入赋值
Ø insert(Tuple, NewValue, Index, Tuple) //编辑形式
1: Tuple := [1,2,3,4,5,6,7,8,9]
2: insert(Tuple,0,3,Tuple)
显示结果为:[1, 2, 3,0, 5, 6, 7, 8, 9]
Ø Tuple[Index] := NewValue //代码形式
1: Tuple := [1,2,3,4,5,6,7,8,9]
2: Tuple[3]:=0
显示结果为:[1, 2, 3,0, 5, 6, 7, 8, 9]

例程:
1: read_image (Mreut, ‘mreut’) //读入图像
2: threshold (Mreut, Region, 190, 255) //阈值化,输出阈值在190-255的Regions
3: Areas := [] //定义数组Areas
4: for Radius := 1 to 50 by 1 //循环
5: dilation_circle (Region, RegionDilation, Radius) //利用半径为Radius的圆对Region进行膨胀运算,输出
6: //RegionDilation,输出形式仍然为Region。
7: area_center (RegionDilation, Area, Row, Column) //输出区域的面积和中心像素坐标
8: Areas[Radius-1] := Area //对数组Areas的第Radius-1个元素进行赋值
9: endfor

3、基本数组操作极其对应的算子
数组操作 说明 对应的算子
t := [t1,t2] t1,t2连接成新的数组 tuple_concat
i := |t| 得到数组长度 tuple_length
v := t[i] 选取第i个元素0<= i < |t| tuple_select
t := t[i1:i2] 选取i1到i2的元素 tuple_select_range
t := subset(t,i) 选取数组t中的第i个元素 tuple_select
t := remove(t,i) 去除数组t中的第i个元素 tuple_remove
i := find(t1,t2) 找到t2数组在t1数组中出现位置索引(or -1 if no match) tuple_find
t := uniq(t) 在t数组中把连续相同的值只保留一个 tuple_uniq
4、创建数组
(1)gen_tuple_const函数
1: tuple_old := gen_tuple_const(100,666) //创建一个具有100个元素的,每个元素都为666的数组
2: tuple_new := gen_tuple_const(|tuple_old|,4711) //创建一个和原来数据长度一样的,每个元素为4711的数组
上面的函数也可以通过如下表达式实现:tuple_new := (tuple_old * 0) + 4711
(2)当数组中的元素不同时,需要用循环语句对数组中的每一个元素赋值
例如:
1: tuple := [] //创建空数组
2: for i := 1 to 100 by 1 //建立步长为1的循环
3: tuple := [tuple,i*i] //将i方的值赋给数组的第i个元素
4: endfor //循环结束

2.4 Halcon的基本函数

算术运算

Ø a / a division
Ø a % a rest of the integer division
Ø a * a multiplication
Ø v + v addition and concatenation of strings
Ø a - a subtraction
Ø -a negation

位运算
Ø lsh(i,i) left shift
Ø rsh(i,i) right shift
Ø i band i bit-wise and
Ø i bor i bit-wise or
Ø i bxor i bit-wise xor
Ø bnot i bit-wise complement

字符串操作
Ø v$s conversion to string //字符串的格式化,有很丰富的参数
Ø v + v concatenation of strings and addition
Ø strchr(s,s) search character in string
Ø strstr(s,s) search substring
Ø strrchr(s,s) search character in string (reverse)
Ø strrstr(s,s) search substring (reverse)
Ø strlen(s) length of string
Ø s{i} selection of one character
Ø s{i:i} selection of substring
Ø split(s,s) splitting to substrings

比较操作符
Ø t < t less than
Ø t > t greater than
Ø t <= t less or equal
Ø t >= t greater or equal
Ø t = t equal
Ø t # t not equal
逻辑操作符

Ø lnot l negation
Ø l and l logical ’and’
Ø l or l logical ’or’
Ø l xor l logical ’xor’

数学函数

Ø sin(a) sine of a
Ø cos(a) cosine of a
Ø tan(a) tangent of a
Ø asin(a) arc sine of a in the interval [-p/2, p/ 2], a Î [-1, 1]
Ø acos(a) arc cosine a in the interval [-p/2, p/2], a Î [-1, 1]
Ø atan(a) arc tangent a in the interval [-p/2, p/2], a Î [-1, 1]
Ø atan2(a,b) arc tangent a/b in the interval [-p, p]
Ø sinh(a) hyperbolic sine of a
Ø cosh(a) hyperbolic cosine of a
Ø tanh(a) hyperbolic tangent of a
Ø exp(a) exponential function
Ø log(a) natural logarithm, a> 0
Ø log10(a) decade logarithm, a> 0
Ø pow(a1,a2) power
Ø ldexp(a1,a2) a1 pow(2,a2)

其他操作(统计、随机数、符号函数等)

Ø min(t) minimum value of the tuple
Ø max(t) maximum value of the tuple
Ø min2(t1,t2) element-wise minimum of two tuples
Ø max2(t1,t2) element-wise maximum of two tuples
Ø find(t1,t2) indices of all occurrences of t1 within t2
Ø rand(i) create random values from 0…1 (number specified by i)
Ø sgn(a) element-wise sign of a tuple
Ø sum(t) sum of all elements or string concatenation
Ø cumul(t) cumulative histogram of a tuple
Ø mean(a) mean value
Ø deviation(a) standard deviation
Ø sqrt(a) square root of a
Ø deg(a) convert radians to degrees
Ø rad(a) convert degrees to radians
Ø real(a) convert integer to real
Ø int(a) convert a real to integer
Ø round(a) convert real to integer
Ø number(v) convert string to a number
Ø is_number(v) test if value is a number
Ø abs(a) absolute value of a (integer or real)
Ø fabs(a) absolute value of a (always real)
Ø ceil(a) smallest integer value not smaller than a
Ø floor(a) largest integer value not greater than a
Ø fmod(a1,a2) fractional part of a1/a2, with the same sign as a1
Ø sort(t) sorting in increasing order
Ø uniq(t) eliminate duplicates of neighboring values(typically used in combination with sort)
Ø sort_index(t) return index instead of values
Ø median(t) Median value of a tuple (numbers)
Ø select_rank(t,v) Select the element (number) with the given rank
Ø inverse(t) reverse the order of the values
Ø subset(t1,t2) selection from t1 by indices in t2
Ø remove(t1,t2) Remove of values with the given indices
Ø environment(s) value of an environment variable
Ø ord(a) ASCII number of a character
Ø chr(a) convert an ASCII number to a character
Ø ords(s) ASCII number of a tuple of strings
Ø chrt(i) convert a tuple of integers into a string

2.5 Halcon的结构语句

  1. if … endif / if … else … endif / if … elseif … else … endif
  2. for … endfor
  3. while … endwhile
  4. repeat … until(循环体至少被执行一次,直到满足条件时退出。等同于C语言的do…while语句)

此外,也有关键字 break、continue、return、exit、stop 用来控制语句的执行;
stop:终止后面的循环,点击Step Over or Run button继续。
exit:终止Hdevelop程序段。

2.6 异常处理

异常处理:
try … catch … endtry:异常算子处理句柄
throw:允许处理用户定义的意外情况。
用MFC写的,我在捕获异常提时候,都需要在前面使用HException::InstallHHandler(&CPPExpDefaultExceptionHandler);才能全try{…}catch(HException &except){…} 生效

在VC中其实是靠不住的。例如下面的代码:
try
{
BYTE * pch ;
pch = ( BYTE * ) 00001234 ; // 给予一个非法地址

  • pch = 6 ; // 对非法地址赋值,会造成Access Violation 异常
    }
    //…是捕捉任意类型的异常.
    catch ( … )
    {
    AfxMessageBox ( " catched " ) ;
    }
    这段代码在debug下没有问题,异常会被捕获,会弹出”catched”的消息框。但在Release方式下如果选择了编译器代码优化选项,则 VC编译器会去搜索try块中的代码, 如果没有找到throw代码,他就会认为try catch结构是多余的, 给优化掉。这样造成在Release模式下,上述代码中的异常不能被捕获,从而迫使程序弹出错误提示框退出。

那么能否在release代码优化状态下捕获这个异常呢, 答案是有的。 就是__try, __except结构,上述代码如果改成如下代码异常即可捕获。

__try
{
BYTE * pch ;
pch = ( BYTE * ) 00001234 ; // 给予一个非法地址

  • pch = 6 ; // 对非法地址赋值,会造成Access Violation 异常
    }
    __except ( EXCEPTION_EXECUTE_HANDLER )
    {
    AfxMessageBox ( " catched " ) ;
    }
    但是用__try, __except块还有问题, 就是这个不是C++标准, 而是Windows平台特有的扩展。而且如果在使用过程中涉及局部对象析构函数的调用,则会出现C2712 的编译错误。 那么还有没有别的办法呢?
    当然有, 就是仍然使用C++标准的try{}catch(…){}, 但在编译命令行中加入 /EHa 的参数。这样VC编译器不会把try catch模块给优化掉了。

(三)算子格式

In the reference manual,operator signatures are visualized in the following way:
operator ( iconic input : iconic output : control input : control output )
在HALCON所有算子中,变量皆是如上格式,即:图像输入:图像输出:控制输入:控制输出。
其中四个参数任意一个可以为空。
控制输入可以是变量、常量、表达式;
控制输出以及图像输入和输出必须是变量。

下面将常见的语法做一个例子跑一下,加深感觉。
read_image (Image, ‘code.png’)
create_bar_code_model ([], [], BarCodeHandle)
dev_set_draw (‘margin’)

  • 同时查找Code 128码和Code 39码,这种方式消耗的时间只等于只找一种码的时间。
  • 得到的字符串元组str等于 [‘123456’, ‘220519140360’]
    find_bar_code (Image, SymbolRegions, BarCodeHandle, [‘Code 128’,‘Code 39’], str)
  • num 长度
    num := |str|
    tuple_strlen (str, Length) //获得字符串元组中每个字符串的长度,[6,12]
    A0 := Length[0] //等于6
    A1 := Length[1] //等于12
    AA := A0 + A1 //等于18
    B0 :=str[0] //得到的仍是一个字符串,‘123456’
    19 B0_int :=number(str[0]) //貌似没有字符串转int类型,不过可以转成number类型,123456
    aa := 3 + B0_int //转为数字可以进行四则运算了,123456 + 3 = 123459
    i :=[590,6] //这里创建的是一个整型元组
    i0 := i[0] //等于590
    *数据转字符串
    aa := 590 + ‘’

为了让程序更容易阅读与调试,尽量一行简短一点。
后话:halcon偏工程类的软件,最好是从工程中学习,从实际问题出发,视觉讲究的解决问题的思路,不同工业上的视觉问题根据图像特点去处理是最好的,没有一个统一的好的方法,只有最合适的。

参考文章 : https://blog.csdn.net/surui_555/article/details/49996155
参考文章:https://blog.csdn.net/jgj123321/article/details/96877135

你可能感兴趣的:(#,Halcon)