快速指引
1
目录
Introducing HALCON................................................................................................................................... 4 1.1 Key Features...................................................................................................................................... 4 1.2 谁应该用 HALCON?..................................................................................................................... 5 1.3 您需要的知识.................................................................................................................................. 5 1.4 开始使用 HALCON.......................................................................................................................... 6 1.5 如何取得更多信息.......................................................................................................................... 6 如何用 HALCON 来开发程序................................................................................................................... 8 2.1 HALCON 的核心: 组织架构以及数据结构................................................................................. 9 2.2 HDevelop 快速入门........................................................................................................................ 12 2.3 在程序语言中使用 HALCON....................................................................................................... 13 2.4 延伸 HALCON 功能...................................................................................................................... 15 2.5 HALCON 的使用极限................................................................................................................... 15 各种行业的应用....................................................................................................................................... 16 3.1 电子零件和设备............................................................................................................................ 16 3.2 食物................................................................................................................................................. 19 3.3 医疗和生命科学............................................................................................................................ 20 3.4 铁、钢和金属................................................................................................................................. 23 3.5 机械................................................................................................................................................. 26 3.6 航空摄影测量和遥感.................................................................................................................... 32 3.7 印刷................................................................................................................................................. 38 3.8 橡胶、合成纤维材料、金属薄片............................................................................................... 39 3.9 半导体............................................................................................................................................. 41
2
第一章
Introducing HALCON
HALCON 是当今machine vision技术的代表,它总是以最新科技为基础,提供了现今市场中最 强大的vision library。不论您的工作为何,HALCON都能快速而精确的解决问题。
Vision Development Environment 一个专业的影像处理工具不能只具有影像处理功能。影像处理只是整个工作的其中一环,还 要有其它软件功能,像是过程控制,数据处理,硬件方面还有照明和取像设备,以及其它硬 体机构等等。一个影像处理系统除了要易于使用,还必须能够以富有弹性的方式将上述功能 加入开发的流程之中。
为此,HALOCN考虑到各种重要的层面: 透过一个交互式的工具HDevelop快速达成软件开发的工作,藉由程序代码的输出,可以轻易的 和标准的软件开发工具,例如Micrisoft Visual C++ 整合。 问题导向式文件涵盖了所有层次,包括取得重点信息到进阶的细项讨论。 文件内容和上千个范例程序连接,让使用者以最直觉的方式了解解决之道,各种范例还可以 作为开发的样本以节省时间。 此外,HALCON也提供了开放的接口以便进行有效率的数据交换,整合自订的运算子,以及 周边的硬设备。
Vision Library
HALCON满足了专业vision library的各种要求:
它包含了各种标准到高阶的功能,从基本的影像处理,取像,到高阶的功能shape- based matching等等。除了针对影像,HALCON还提供了机器视觉应用中常用的功能,例如socket 通讯以及rs232的沟通,档案存取,数据分析,算数运算,或是分类等等。富有弹性的平行 计算方式可在多处理器的硬件上提升速度。一般的使用者看不到系统是用HALCON开发的, 安装时需要的资源也很少,非常适合OEM厂商。
1.1 Key Features
最先进的科技
除了提供了完整的标准 machine vision功能,还有一系列优异的功能,例如,3D相机校正, 形状以及原件导向的匹配,次像元精度的物体撷取,计算,利用双像立体量测,任意形状的 ROI,以及更多的功能。此外,某些library具有的功能,像是morphology,整合在HALCON之 下,其计算效能比起其它产品提高近百倍之谱,也提供了更多的使用弹性。
能符合所有应用的单一软件 HALCON包含了1100多种各类功能,可用于任何和影像相关的研究以及产品开发,全世 界已有许多使用者利用HALOCN解决了machine vision方面的问题。 保障您的投资 选择HALCON,您选择了独立性。需要转换一个作业平台?HALCON支持了许多作业平台, 从微软的Windows NT/2000/XP,Linux,到UNIX。要将程序由C++改为C#来开发?HALCON可
3
用于多种程序语言与开发环境。您的计算需求日增,需要更有力的计算工具?换到一台多处 理器的计算机上,HALCON可以自动进行平行处理。还有,您可以自行选择想要使用的取像设 备,HALCON已经提供了多种即用的取像设备连结接口,例如 analog,digital,IEEE1394,CameraLink等等不同的取像设备。
快速建立雏形 在许多状况下,您必须在最短的时间内决定问题的解决方案。HALCON提供的HDevelop是一 个交互式的快速发展工具,具有成熟的程序编译以及除错功能,同时还提供了可能使用的运 算建议,并且自动显示计算结果。藉由整合的工具,您可以检视影像以及任意阶段的计算结 果,得以快速的决定各种参数。
开放的架构
HALCON提供了市场上最强大的 vision library,但它却不是一个封闭的套件。它有个开放性 的架构,也就是说您可以新增自己的计算功能。此外,如果您想要使用的frame grabber目前 HALCON尚未支持,您还是可以直接读取内存或是自行另外开发一个接口来整合。
1.2 谁应该用 HALCON?
简单的说,就是所有用到机器视觉软件的人。 HALCON可说是为了下列的人们设计的:
OEMs设备商,例如芯片或印刷检验机;软件开发者,例如车牌辨认和细胞分析;客户指定 功能之机器视觉设备的系统整合者。对于研究机构,大学,完整的计算功能使其或益良多, 尤其是HDevelop这个交互式的工具用于雏形开发上有极佳的成效。
1.3 您需要的知识
影像处理 当然,您对影像处理的专业术语和标准方法越熟悉,越容易用HALCON来解决问题。在第5 章简要的介绍了这些方法,也说明了在HALCON中要如何使用。您也可以由第3章或是第4 章着手,其中说明了不同工业以及应用的例子以及使用的计算方式。
程序设计
如果您要在某个程序语言中使用HALCON,您就必须熟悉该种语言以及相关工具。 HALCON Programmer’s Guide 说明了HALCON的语言接口,数据型态和类别,呼叫运算子的方法等 等。
操作系统
您需要对目前使用的操作系统有基本的了解,才能安装HALCON以及其license等等。
4
1.4 开始使用 HALCON
想对HALCON有所认识,我们建议您安装demo版的HDevelop,不必使用license。它一样提供 了所有的影像计算功能,唯一的限制是不能连接取像接口,撰写的程序也不能储存。有了 demo版的HDevelop,您就可以踏入HALCON的世界,透过范例程序,了解它的能力。2.2节 有简要的介绍。您可以由MVTec 的网站或是CD来安装,要注意的是,CD之中并不包含所有 的版本。如果要评估完整的功能和测试,例如包含取像设备的运作,或是在程序之中加入 HALCON的功能,您可以向当地的代理商(新亚洲仪器公司)索取当月份的试用license。License 安装与使用的详细说明请参阅 HALCON Installation Guide. 1.4.1如何从CD安装demo版的 HALCON 在HALCON Installation Guide.中有详细说明
1.4.1.1 Windows NT/2000/XP Platforms
要进行下列步骤,您必须有 administrator 权限
将 CD 置入 CD-ROM 中。如果安装没有自动开始,请由CD目录的 nt-x86中,执行Setup.exe。 安装程序会自动说明相关事宜,并且引导您完成安装程序。Setup之中会让您选择安装型式, 在此请选择安装Demo版,安装完成后,你可以直接由Windows的程序集中执行HDevelop,不 必再经过其它额外设定。 1.4.1.2 UNIX 平台
将CD置入CD-ROM中,并将其连接到系统中。您可能需要root 权限才能完成硬件连接设定。 由CD根目录执行 shell script install-unix 。这个 script 会问您想要安装的路径,您也可以选择 想要安装的原件,不过您只要依照程序的建议,选用默认值即可。安装后要设定环境变量, 安装程序会告知您要做的动作。要启动展示版的HDevelop,由shell中执行之。
1.4.2如何由因特网上安装HALCON的展示版
MVTec的下载区位于 http://www.mvtec.com/download ,您必须先注册才能下载。 选择demo version以及您的操作系统,再依照指引操作。在 Windows NT/2000/XP 下,由\"开始\"\"程序 集\"下可以找到展示版的HDevelop来执行。 UNIX ,由 shell中执行。
1.5 如何取得更多信息
藉由本手册
第二章中说明了如何在HDevelop中发展程序,或是在支持的程序语言中使用HALCON。 第三以及第四章分别以machine vision industry 以及 application area 两种分类方式来介绍 HALCON的范例程序
第五章叙述了machine vision中主要的方法,以及在HALCON之中要怎样使用这些功能,以及 范例程序。
HALCON Installation Guide
这本手册说明了不同的安装授权方式,以及安装,升级,解除安装的详细方法。
5
HDevelop User’s Manual 这本书详细的介绍了HDevelop这个程序设计环境,书中解释了它的图形接口,撰写程序使用 的语法,输出成其它语言,等等。
HALCON Programmer’s Guide 如果您要在C++或是VB等等程序语言中使用HALOCN,请参考这本手册,其中说明了相关的 接口,数据型态,类别等等。
Extension Package Programmer’s Manual
这本手册说明了如何将自订或自行设计的计算功能加入HALCON之中。
Frame Grabber Integration Programmer’s Manual
如果您使用的取像器HALCON尚未支持,这本手册说明了开发取像系统连接接口的方法。
Application Guide
这本手册目前包含了三个部分
1.Application Note on Shape-Based Matching: 说明了如何使用HALCON的shape-based matching 来 找寻物体。内容以影像中的单一 model 为例,说明以其进行次像元精度定位的方法。 2.Application Note on 3D Machine Vision: 这段落说明了 3D machine vision 的原理与方法。
3.Application Note on Image Acquisition: 这段落说明了取像接口的基本以及进阶设定方式,以 及各种计时模式等等。
Reference Manuals
包含了HALCON所有运算子的说明,针对 HDevelop, C++, COM, and C 等等四种语言各有其独 立的文件。
Release Notes
如果您有使用旧版的HALCON,请抽空看一看。这份文件位于您的HALCON安装目录下,名 为 notes.html
Example Programs HALCON提供了为数可观的范例程序,除了HDevelop的程序,也提供了其它程序语言例如VC 或VB等等的程序范例。这些程序位于安装目录下的 examples 目录中。其中有许多的例子在 手册之中都会提到。
Support 对HALCON有任何问题,请联络当地代理商(新亚洲仪器公司) http://www.idsvision.com.tw/
Training Seminars
某些代理商会举办 training seminars ,相关消息可以由各代理商或是 HALCON 网站 新亚洲仪器公司 http://www.idsvision.com.tw/
MVTec公司 http://www.mvtec.com/halcon/support/training.html 查询
6
第二章 如何用 HALCON 来开发程序
您可以用不同的方式以HALCON的功能来建构一个应用程序。但是最有效率的方式是采用下 图所建议的流程:
图2.1发展软件的三个步骤
上图说明了这个流程:利用HDevelop检视分析影像,建立计算雏形,最后完成视觉计算方法 的发展。程序可以分成不同的子程序, 每个procedures可以只做一件事,像初始化,计算, 或是清除。主程序用于呼叫其它子程序,传递影像或是接收显示结果。最后,程序输出成我 们要用的程序代码,接续下一步工作。
完整的程序发展是在程序设计环境中进行,像是 Microsoft Visual Studio 。由HDevelop输出的 程序代码,透过指令加入程序中(例如include)。至于程序的接口等等则是利用程序语言的功能 来建构,接下来,compiled and linked,产生应用程序。自行撰写的程序和 HALCON library一 起装入机器中出货,或是将程序卖到客户处。 图2.1说明了这个流程的概念,这个三步骤的发展方式有几个好处:
1.由于HDevelop提供了极佳的影像检视以及除错机制,系统中的vision部分很容易新增功能或 是修改,不需要在一般的程序语言环境下进行除错。
2.HDevelop输出的程序代码可以轻易的和程序语言结合,缩短撰写时间。
3.由于vision计算的程序代码和程序其它部分无关,因此可以独立执行开发测试,不必跟随整个 项目进行发展。
7
4.从技术支持的层面来说,只要将HDevelop程序代码交给厂商即可,可大幅提高服务效率。
5.由于HDevelop可在不同的操作系统下执行,像是Linux,因此开发好的程序可以轻易的达到 跨平台的使用便利性,这和一般的微软系列的程序开发工具大不相同。
2.2章说明了如何在HDevelop中建立雏形的基本信息,2.3章说明如何将HDevelop输出的程序代码 整合到程序之中。至于程序语言的开发环境诸如 Microsoft Visual C++等等,请参考相关软件 厂商的文件。
2.1 HALCON 的核心: 组织架构以及数据结构
HALCON的架构,数据结构以及内部管理机制是依据以下的哲理来设计的
1.效率 2.开放 3.标准化 4.自我叙述
效率是指HALCON尽可能地缩短每个运算子的执行时间。进一步的,即使进行一连串的复杂 计算,依旧能维持良好效率。开放的架构是基于两种重要的考虑,首先,HALCON要能用在 不同的程序语言中,因此必须能对外进行数据交换以及读取内部数据。开放而透明的架构才 能整合使用者自订的计算功能甚至是一些非标准的取像设备。此外,这种方式也使得外围设 备有更动或更新时,不必再重新安装HALCON一次。标准化是指运算子的命名,功能以及使 用方式,数据结构等等都遵循一个严格的限制,这使得使用者有最快的学习效率,也降低了 犯错机会。最后,HALCON对每个运算子都有详细的说明,除了详尽的文件,特定的运算子 也可以读取这些说明数据。
图 2.2: HALCON 的基本架构
图2.2中可见其基本架构。主要的部分是 image processing library,包含了大量的运算子, 提供了所有的功能。运算子透过所谓的语言接口来操作,可以用不同的程序语言来呼叫其中 的功能,或是用动态连结的方式加载。图片的左侧是所谓的取像接口,右侧是使用者自订的 延伸功能。更深入来说,有两大要点:即运算子和数据结构。
8
2.1.1 HALCON 的运算子
HALCON中各种运算功能皆是透过运算子来完成。目前的版本约有 1100 多个运算子。其中 大部分都有多重的计算功能,你可以透过参数来选择计算方法。在参考手册或是HDevelop主 选单中的Operators中都有完整的列表。这些运算子之间其实是没有任何继承关系,但是可以 依据功能来分类。您可以在C++或是COM手册中看到这些类别,相同类别里的运算子成员处 理类似的数据。所有运算子的输入输出参数排列方式都有相同的规则,请看 2.1.2。运算子 的设计依循开放式的架构,您可以设计自己需要的运算子,加入HALCON,感觉上就像暨有 的功能一般 (请看 2.4.1)。许多运算子可以藉由自动并行计算机制来加快速度,尤其是以多 处理器的计算机来处理大尺寸的影像时效果尤着。 (请看 2.1.3). 2.1.2 参数和数据结构
HALCON 有两种基本的数据型态: 图像数据(iconic,例如影像 )以及控制数据( control,例如 变量,整数,字符串,handle等等)。所有运算子的参数都是以相同的方式排列:输入图像,输 出图像,输入控制,输出控制。当然,并非所有的运算子都具有上列四类参数,不过参数排 列的次序依旧相同。每个运算子都有一个自我叙述接口,除了标准文件,还有参数类型,或 是可用的数值,都可在联机操作时获得。计算过程中运算子的输入参数内容不会改变,仅有 的三个例外是 set_grayval, overpaint_gray 以及 overpaint_region。 开放的架构让您可以取得内部数据,以便和外部数据整合。在处理2D影像时需要用到的各 种数据结构像是影像(例如多频道影像), region, contours,tuples (一种数组)等等,都提
供了一种快速有效的存取功能。关于这些低阶数据结构的说明,请参考 Extension
Package Programmer’s Manual 之第四章。 至于程序语言中可用的数据型态或类别,请 参阅HALCON Programmer’s Guide. 2.1.2.1 影像 影像
属于图像数据
影像中的主要部分是个别的频道,他们是由代表不同像元型态的灰阶值数组构成。每张影像 都有其定义域(domain),代表影像中要处理的数据范围。这就成为所谓的 region of interest (ROI),定义域本身就是一个HALCON的region,具有无比的弹性,例如从一个简单的矩形到 任意形状。
像元资料
像元数据几乎可为任何型态,从 8-bit 灰阶到浮点数皆可。整数,从1到4bite。浮点数,或是 complex images 也可处理。此外,还包含了表现边缘方向或是 hue 的特别数据型态。
影像频道 频道即是影像中某一个数据数组。影像可含有任意数目的频道。同一影像中的所有频道都有 相同的尺寸。最常见的影像是单频道的灰阶影像,或是三频道的彩色影像(例如RGB),多光 谱影像,或是多种纹理分类使用的影像。
坐标系统
影像是以左上角为坐标原点 (0,0)。每个像元是以row 和 column 表示其坐标。坐标值的范围从 (0,0) 到 (height-1, width-1)。每个像元的尺寸为1,第一个像元的中心坐标为 (0,0),因此第一
9
个像元的范围是从(-0.5, -0,5) 到 (0.5,0.5)。
2.1.2.2 Regions
Region属于图像数据。
所谓region 即是一堆像元的集合。但是他们的坐标范围不受影像大小的限制。region中的像元 不一定要相连,也就是说任意形状的像元集合都可成为一个region,如果要让相连接的像元 成为一个region,只要呼叫运算子 connection 即可。由于region内的像元坐标范围并非受限于 某张影像,region可大于影像范围,例如进行region扩张运算时就有可能会超过。至于要不要 将尺寸限制在影像大小范围内,可透过运算子 set_system ,配合参数 'clip region'来设定。 region是由一种runlength encoding数据组成的,内存使用量极低,却有很好的速度和效率。 由于region不是以一般软件的 label images 来控制,因此可以互相重迭,例如扩张运算的结 果,一般的软件无法做到这一点。至于程序中允许的region数目,并无特别限制。
2.1.2.3 XLDs
XLDs (属于iconic data).
XLD 是 eXtended Line Description 的缩写,包含了所有等值线以及多边型的数据。像 edges_sub_ pix 之类的次像元精度运算子产生的数据即属于 XLD 。
一条所谓的2D等值线是一连串坐标点的串行,相邻两点间以直线相连。一般来说,数据点 之间的距离大约是1Pixel。XLD对象中除了点坐标数据,还包含了全域或区域属性,例如 edge方向,或是分割时的regression参数等等。除了取出XLD数据,还能做进一步的应用,例 如选择具有特定特征的曲线,或是把曲线分割成直线段,圆弧,多边型,或是并行线等等。
2.1.2.4 Control Tuples
Tuples就像一个数组,其中的数据型态可为整数,浮点数或是字符串。一个tuple型态的变量可 为上述三种数据型态之一,甚至于混合。当我们计算一个region的某些特征时,会传回一个 结果,如果计算的是一群region,会传回一个tuple,其中含有每个region的特征计算结果。 Control tuple的指标由0开始。请注意,iconic tuple的指标由1开始。 2.1.2.5 Handles
Handles是用于管理一组复合的数据,例如 shape-based matching 中的models。为了程序设计的 方便性以及数据安全与效率,这类数据只透过一个handle 让使用者操控。每个Handle都有一 个唯一的整数数值,由系统底层自行产生。例如图形窗口,档案,sockets,取像设备,
OCR, OCV,measuring, matching等等,都会以handle来代表要操作的对象。
2.1.3 Parallel HALCON
简单的说,标准版的HALCON 是为了在单处理器的计算机上进行循序式计算而设计的。在 Windows NT/2000/XP, Linux,以及 Solaris等等系统下,HALCON 是 thread-safe,也就是能用 于 multi-threaded 程序。然而程序执行时,每个运算子都是独一的,也就是执行绪间要互相等 待。相对的,Parallel HALCON 支持所谓的 parallel programming (e.g., multi-threaded programs), 他同时是thread-safe 以及 reentrant。这意味着多个执行绪可同时呼叫同一个运算子。平行运算 版本的 HALCON 支持 Windows NT/2000/XP, Linux, 以及 Solaris。除了支持平行运算,平行
运算版本的HALCON在多处理器的计算机上能自动进行数据平行化,分配到不同的处理器去作 业,例如影像。举个例子,在一个4处理器的计算机上进行影像的滤波计算,影像会被分成四
1
份,由4个执行绪分别在4个处理器上进行相同的运算。以HALCON处理影像以及region的 设计哲理来说,由于影像不必再经复制,所以这种平行化是一个最有效率的方法。至于平行 化的程度还能由在线控制,避免平行化进行过度。例如,太小的影像就不应该进行平行化, 否则往往只会降低速度。此外,并非所有的 运算子都支持平行处理。这部分的详细说明请 参阅 Programmer’s Guide,第一章。注意, Parallel HALCON 是针对 shared-memory systems 设计的,例如多个处理器使用共享内存的架构,主要理由就是因为这种架构下各个执行绪 需要的数据不必再复制一次。这也意味着HALCON不能用于cluster式内存或是处理器使用 个别内存的工作站。
2.1.4 取像
目前 HALCON 提供了 40 余种取像设备连接接口,并以动态连结的方式加载。(Windows: DLLs; UNIX: shared libraries).这些 libraries 随着 HALCON一起安装到计算机中。他们的名称一律
以 HFG开头,至于以 parHFG开头者是用于Parallel HALCON。关于取像作业的详细说明请参 考Application Note on Image Acquisition 。这些取像接口将HALCON与硬件制造商提供 的驱动软件结合,成为一个标准化的共同接口,不论您使用的的硬件为何,只要透过少数几 个运算子就能操作。当您安装了影像卡以后,要透过 HALCON 使用它,只需要呼叫 open_ framegrabber,并设定相关的参数。接下来,只要用grab_image 或 grab_image_async 即可取得影像。HALCON 的frame grabber 接口常常在更新,比HALCON library 本身还频繁。 理由之一是因为 MVTec 持续在发展新的接口,另外就是为了配合取像设备厂商的软件更 新。最新的接口以及相关文件可由http://www.mvtec.com/halcon/framegrabber下载。
2.2 HDevelop 快速入门
HDevelop 是一个强大的建构雏形以及发展方法的强大环境。要使用HDevelop ,您只需知道 一点点东西。建议您从MVTec提供的 680 多个立即可以执行的程序着手浏览。这部分细节请 您参考HDevelop User’s Manual。在Windows NT/2000/XP下,由开始 > 程序集 > MVTec HALCON 7.0 > HDevelop 来执行HDevelop。 UNIX系统下,在 shell 中执行 hdevelop。要加载 范例程序,只要从程序主选单的File > Open 开启一个档案选择对话框,此时的目录是位于 主要的范例所在目录,建议各位初学者由 Applications这个目录下的范例程序开始着手。此 外,由程序主选单 File > Open Example Program... 则可开启一个对话框,由此可以根据不同的 分类方式来选择范例。程序加载后,程序窗口中即显示出程序代码,变量窗口中择显示出所有 用到的变量,由于尚未执行,各个变量是以?表示其尚无内容。简易使用方法如下:
1.要执行程序,按RUN(F5)即可,若程序停在stop指令上,再按一次RUN(F5)即可继续。 2.除了RUN,HDevelop还提供了STEP(F6),可让您一行行的执行程序并且检视成果。如果程 式中含有其它的副程序,利用STEP则可 Step Into 以及 Step Out。 3.要重新执行程序,按Reset(F2)即可让程序回到起点。
4.想要执行一部份的程序,只要在程序窗口中,用鼠标左键在想要的程序行左侧点一下,将 绿色的 program counter 放在该处,程序就可以由该行开始执行。
HDevelop的提示:
1. 程序窗口下方有一个状态列,这里会显示一些很有用的参考信息。例如各个运算子的执行
1
时间,或是当程序因为stop指令停止时,或是等候使用者输入(例如画region)等等。
2. 许多程序会在图形窗口中显示成果,您也可以在变量窗口中在想要显示的对象上点两下, 便可以手动的方式将物体显示在图形窗口中。
3. 依据您选择的安装方式,并非所有的影像都会复制到计算机中。如果有短少程序需要的影 像,建议您将 HALCON CD 置入光盘中,或是安装需要的影像。
4. 有些程序会开启 frame grabbers 进行取像,若系统中没有对应的取像设备,则会出现错误 讯息。遇到这种情况则建议您选择另一个程序来执行,或是修改程序中的参数以符合现行使 用的硬件。另外,如果您执行的是Demo版的HDevelop,将无法进行任何取像动作。
2.3 在程序语言中使用 HALCON
HALCON提供了三种语言接口, 让您在所使用程序语言中呼叫使用 HALCON library 强大的 功能却不失使用上的便利。其中 C 和 C++ 接口是特定语言使用的,但是 COM 接口并不限定 使用语言,你可以在 Visual Basic, C#,或是 Delphi中使用。依据您使用的语言,对应的介 面(halconc.*, halconcpp.*,halconx.*) 要和HALCON library (halcon.*) Link到程序中。在 C 以及
C++ 语言中,要加入对应的 include files 。在着手进行开发前,建议您先试着执行HALCON中 提供的各种语言范例程序,由此您可以了解项目中必要的设定以及相关的数据型态宣告方 式。各种语言接口中用的语法以及数据型态,类别等等稍有不同,详细的说明详见 HDevelop ,C++, COM (Visual Basic) 以及 C 的参考文件。 2.3.1 C
这个接口是最简单的一种。每个运算子有一到二种全域函数,其名称和参数顺序和在 HDevelop中一致。所有的参数都能接受tuple型态的输入数据。这些运算子名称都是以T开 头,如果不会用到tuple作为输入,则可用另一种只使用基本数据型态(long, double, and char*) 的运算子。 Hobject 以及 Htuple 分别用来宣告图像以及控制数据。
由于 C 不含解构功能,因此你必须利用 clear_obj 来释放宣告的图像变量。复制,产生, 清除或是处理tuple数据时,会用到 macros 功能。详细资料请看HALCON Programmer’s Guide, 第四部分。下列的程序代码说明了如何由档案读取一张影像,并且显示在图形窗口 中。
read_image(&Monkey, \"monkey\");
get_image_pointer1(Monkey, &Pointer, Type, &Width, &Height); open_window(0, 0, Width, Height, 0, \"visible\ disp_obj(Monkey, WindowHandle);
2.3.2 C++
C++ 接口要比C精巧得多。C++语言的特长以及对象导向的语法让使用上更为便利,例如自 动型态转换,建构与解构,或是将处理同类型数据的功能集合成一个类别。和在C界面中一 样,每个运算子都有一个全域函数让您可以使用程序式的程序设计语法,此时可用Hobject 以及 HTuple 两个类别,以对象导向式的来说,可用到的包含HDataCode2d,HMeasure或是 HshapeModel....等等,至于其它的类别请参考 HALCON Programmer's Guide, part II. 下列程序代码说明了读取影像,显示在图形窗口中,并且进行一些基本的 blob 分析。
1
HImage Mandrill(\"monkey\"); HWindow w(0, 0, 512, 512); Mandrill.Display(w);
HRegion Bright = (Mandrill >= 128);
HRegionArray Conn = Bright.Connection();
HRegionArray Large = Conn.SelectShape(\"area\ 2.3.3 Visual Basic
和C++类似,您可以用对象式或是程序式的语法。以程序式的语法,您使用的是
HOperatorSetX 这个类别,其中提供了所有运算子的呼叫,HUntypedObjectX 代表所有图像资 料,内建的 Variant 则是用于控制数据。对象导向式的写法,用到了各种类别,像是
HDataCode2dX, HMeasureX,或是 HShapeModelX ....等等。至于其它的类别请参考 HALCON Programmer's Guide, part III
下列程序代码说明了读取影像,并且进行一些基本的 blob 分析。
Dim image As New HImageX Dim region As HRegionX
Call image.ReadImage(\"monkey\")
Set region = image.Threshold(128, 255)
2.3.4 C#
如同 Visual Basic, C# 使用 HALCON 的 COM 接口。也就是说和VB中的用法相同。唯一的差
异是在.NET中 Variant 数据型态称之为 Object, C# 中也是如此。 下列是C# 程序范例:
1
HImageX image = new HImageX(); HRegionX region;
image.ReadImage(\"monkey\");
region = image.Threshold(128, 255);
2.4 延伸 HALCON 功能
2.4.1Extension Packages (User-Defined Operators)
HALCON 可透过新增运算子以延伸功能。 HALCON 虽然已提供了1100 多个运算子,或许您 还是想新增一些功能,例如整合某些硬件或是新的运算方法。为此, HALCON 提供了所谓 的 Extension Package 接口,让您可以整合加入新的运算子(以C撰写)。他提供了一些预先设定 的程序和宏,让您可以掌控影像对象以及内存的使用。一旦新的运算子完成整合,使用 上就和HALCON暨有的功能一般。在 Extension Package Programmer’s Manual 包含了 详细的说明。
2.4.2Frame Grabber 界面
frame grabber 接口的整合是透过动态结数据库。以这种方式新增接口就不必动到系统中的其 他部分。接口产生以及整合方法在Frame Grabber Integration Programmer’s Manual. 有 叙述。此外,HALCON 包含了一套样板程序代码作为自行开发时的基础。
2.5 HALCON 的使用极限
影像尺寸 32768*32768 内存中影像数组数目 100000 每个参数包含的对象数目 100000 每张影像的频道数 1000 tuple中的数值数据数目 1000000 一条等值在线的取样点数目 30000 一个多边型上的控制点数目 10000 影像坐标 -32768 到
+32768 字符串长度 1024个字符
1
第三章
各种行业的应用
3.1 电子零件和设备
3.1.1 检查 Dip Switch 的状态 范例:
examples\\hdevelop\\Applications\\FA\\cbm_dip_switch.dev
这个范例的任务是要检查 Dip Switch ,即计算外壳与各个开关间的相关位置(见图 3.1)。
(a) (b)
图 3.1(a)dip switch 的影像中各部份的 ROI。(b)位于 dip switch 的开关状态。
这个任务是使用以组件为基础的比对方法来解决。在图 3.1a 中,Dip switch 一共有 14 个 部份,其中包含 12 个开关和 2 个在外壳上的印刷文字。在影像显示出所有可能的开关位置 后,即完成对影像的教导,此外系统也会学习外壳与开关间相对位置的变动。 train_model_components (ModelImage, InitialComponents, TrainingImages,
ModelComponents, 45, 45, 30, 0.95, -1, -1, rad(20), 'speed', 'rigidity', 0.2, 0.5, ComponentTrainingID)
在教导中加入少量的误差容许值变动,使影像的识别更加可靠。 modify_component_relations (ComponentTrainingID, 'all', 'all', 0, rad(4)) 现在可以产生这个模型了
create_trained_component_model (ComponentTrainingID, 0, rad(360), 10,
MinScoreComp, NumLevelsComp, 0, 'none', 'use_polarity', 'false', ComponentModelID, RootRanking)
1
在搜寻 dip switch 时,不止是搜寻外壳与 dip 的相对位置关系,还包含每个个别 dip 间的 相对位置。经由这些信息,可以很容易的得知开关所有的状态。
find_component_model (SearchImage, ComponentModelID, RootRanking, 0,
rad(360), 0, 0, 0.5, 'stop_search', 'prune_branch', 'none',
MinScoreComp, 'interpolation', 0, 0.9, ModelStart, ModelEnd, Score, RowComp, ColumnComp, AngleComp, ScoreComp, ModelComp)
3.1.2 检视电源供应线
范例:examples\\hdevelop\\Filter\\Lines\\lines color.dev 这个范例的任务是电源线的定位和检查,详细见图 3.2
(a) (b)
图 3.2:(a)利用有颜色的线条,在原始的颜色影像中,取出电源线的中心(b)相同的影像结果 使用灰阶值的影像来作。
底下程序的输入项,是一个有颜色的电源线影像样本。它的任务是为了取出每条电源线 的中心和宽。完成此行程序后,使用次像元精度的颜色线来解析,并将太短的轮廓线删掉, 去除不相关的部份。
lines_color (Image, Lines, 3.5, 0, 12, 'true', 'false')
select_contours_xld (Lines, LongLines, 'contour_length', 450, 100000, 0,
0)
经由撷取线宽的特性,判定电源线的宽度。为了显示这个目的,要产生每一个边的轮廓线。
Number := |LongLines| EdgesL := [] EdgesR := []
for K := 1 to Number by 1
Line := LongLines[K]
1
get_contour_xld (Line, Row, Col)
get_contour_attrib_xld (Line, 'angle', Angle)
get_contour_attrib_xld (Line, 'width_right', WidthR) get_contour_attrib_xld (Line, 'width_left', WidthL) EdgeRR := Row+cos(Angle)*WidthR EdgeRC := Col+sin(Angle)*WidthR EdgeLR := Row-cos(Angle)*WidthL EdgeLC := Col-sin(Angle)*WidthL
gen_contour_polygon_xld (EdgeR, EdgeRR, EdgeRC) gen_contour_polygon_xld (EdgeL, EdgeLR, EdgeLC) EdgesL := [EdgesL,EdgeL] EdgesR := [EdgesR,EdgeR]
endfor
把解析的结果和传统的方法作比较,让线形解析也应用于灰阶值影像。这个结果被显示 在图 3.2(b)中。这里,由于影像仅仅由光线的照明而变的明显,因此可以清楚的看到其成果 是较不如用有颜色的线条来作分析。
rgb1_to_gray (Image, GrayImage)
lines_gauss (GrayImage, LinesGray, 3.5, 0, 0.7, 'dark', 'true', 'true',
'false') 3.1.3 其它的范例
HDevelop
examples\\hdevelop\\Applications\\FA\\cbm bin switch.dev
使用以组件为基础的比对,找出一个开关并且测试它的状态。
examples\\hdevelop\\Applications\\FA\\holes.dev 取出洞的位置和半径
examples\\quick guide\\hdevelop\\fuse.dev 测量保险丝的厚度
--->在 Quick Guide 中有这里的描述
1
3.2 食物
3.2.1 \"食用期限\"的日期
范例:examples\\hdevelop\\Applications\\OCR\\bottle.dev 这个范例的任务是检视在瓶盖上\"食用期限\"的日期
(a) (b)
图 3.3:(a)原始影像(b)读取的日期
这个必需使用多个步骤才能解决。首先,要撷取黑暗的区域,之后处理太薄的部份。 threshold (Bottle, RawSegmentation, 0, 95)
fill_up_shape (RawSegmentation, RemovedNoise, 'area', 1, 5) opening_circle (RemovedNoise, ThickStructures, 2.5) fill_up (ThickStructures, Solid)
下一步,将 region 分割成单独的字符;即使是太过于靠近而互相接触的字符也都可以被分离 出来。
opening_rectangle1 (Solid, Cut, 1, 7) connection (Cut, ConnectedPatterns)
intersection (ConnectedPatterns, ThickStructures, NumberCandidates) select_shape (NumberCandidates, Numbers, 'area', 'and', 300, 9999) sort_region (Numbers, FinalNumbers, 'first_point', 'true', 'column')
最后,进行 OCR 的读取
read_ocr_class_mlp (Name+'.fnt', OCRHandle)
do_ocr_multi_class_mlp (FinalNumbers, Bottle, OCRHandle, RecNum, Confidence)
3.2.2 其它的范例
HDevelop
examples\\hdevelop\\Applications\\OCR\\bottlet.dev 分离和教导啤酒盖上的数字
C++
examples\\cpp\\source\\bottle.cpp 读取啤酒盖上的数字
1
3.3 医疗和生命科学
3.3.1 分析颗粒
范例:examples\\hdevelop\\Applications\\Medicine\\particle.dev
这个范例的任务是分析液体中的颗粒。在这项应用中的主要困难是,存在二个不同类型的 物体,一个是较大又明显的物体,另一个是较小且对比不明显的物体。此外噪声的存在更使 这个分离更复杂。
程序片断中的二个件物类别,分别使用二个不用的方法:全域和区域的临界值。增加一个 后处理,让较小的颗粒以可靠的方法被撷取出来。
(a) (b)
图 3.4:取出较小的颗粒(a)原始影像(b)结果
threshold (Image, Large, 110, 255)
dilation_circle (Large, LargeDilation, 7.5) complement (LargeDilation, NotLarge)
reduce_domain (Image, NotLarge, ParticlesRed) mean_image (ParticlesRed, Mean, 31, 31)
dyn_threshold (ParticlesRed, Mean, SmallRaw, 3, 'light') opening_circle (SmallRaw, Small, 2.5) connection (Small, SmallConnection)
1
3.3.2 血管造影法
范例:examples\\hdevelop\\Filter\\Lines\\lines gauss.dev
这个范例的任务是去撷取,在图 3.5 中心脏的 x 光照片影像中的血管。在经由适当的对比 之后,血管可被突显出来。然后撷取血管的宽度,来判断区域中狭小的部份(狭窄症),这对 诊断而言是很重要的。
(a) (b)
图 3.5:(a)心脏的 x 光照片影像(b)撷取血管
使用 line_gauss 来撷取血管影像。这项作业的结果是从 XLD 轮廓线中找出血管的中心。 其中一项的属性是区域线的宽度,这个宽度如同轮廓线一般是必要的,并且要被显示出来。 lines_gauss (Angio, Lines, 2.2, 0, 0.8, 'dark', 'true', 'true', 'true') Number := |Lines|
for I := 1 to Number by 1
Line := Lines[I]
get_contour_xld (Line, Row, Col)
get_contour_attrib_xld (Line, 'angle', Angle)
get_contour_attrib_xld (Line, 'width_left', WidthL) get_contour_attrib_xld (Line, 'width_right', WidthR) RowR := Row+cos(Angle)*WidthR ColR := Col+sin(Angle)*WidthR RowL := Row-cos(Angle)*WidthL ColL := Col-sin(Angle)*WidthL
disp_polygon (WindowID, RowL, ColL) disp_polygon (WindowID, RowR, ColR)
endfor
2
3.3.3 其它范例
HDevelop
examples\\hdevelop\\Applications\\Medicine\\angio.dev 从血管造影中撷取血管和它的直径
examples\\hdevelop\\Applications\\Medicine\\vessel.dev 血管的分离和测量
examples\\hdevelop\\Manuals\\HDevelop\\particle.dev 测量较小的颗粒
--->描述在 HDevelop User’s Manual
examples\\hdevelop\\Manuals\\HDevelop\\vessel.dev 微血管的撷取
--->描述在 HDevelop User’s Manual C++
examples\\cpp\\source\\example5.cpp 分析细胞大小的分布
2
3.4 铁、钢和金属
3.4.1 检视铸造零件
范例:examples\\hdevelop\\Applications\\Measure\\measure arc.dev
这个范例的任务是要检视零件在挖槽之后,其瘦长凹洞间的距离(见图 3.6)。注意,要达成一 个最正确的测量,这里我们建议使用背光板配合 telecentric 镜头
图 3.6:测量洞与洞之间的距离
使用环形量测的 ROI 来作为测量的工具,可以容易的解决这个任务。我们将 ROI 的中 心放置于 cast part 的中心处;并将它的半径设成从中心到瘦长凹洞的距离。 Row := 275 Column := 335 Radius := 107
AngleStart := -rad(55) AngleExtent := rad(170)
gen_measure_arc (Row, Column, Radius, AngleStart, AngleExtent, 10, Width, Height, 'nearest_neighbor', MeasureHandle)
现在,洞与洞之间的距离,只要用底下一行运算子呼叫即可测量出:
measure_pos (Zeiss1, MeasureHandle, 1, 10, 'all', 'all', RowEdge, ColumnEdge, Amplitude, Distance)
2
3.4.2 其它的范例
Hdevelop
examples\\application guide\\shape matching\\hdevelop\\align measurements.dev 使用以形状为导向的匹配之直线 ROI 测量工具,来检视个别的刮胡刀片 --->在 Application Note on Shape-Based Matching 有详细的介绍
examples\\application guide\\shape matching\\hdevelop\\multiple models.dev 同时搜寻二种形状的物体
--->在 Application Note on Shape-Based Matching 有详细的介绍
examples\\application guide\\shape matching\\hdevelop\\multiple objects.dev 搜寻安全环的例子
--->在 Application Note on Shape-Based Matching 有详细的介绍
examples\\application guide\\shape matching\\hdevelop\\multiple scales.dev Searches for nuts of different sizes
--->description in the Application Note on Shape-Based Matching 搜寻不同尺寸的螺帽
--->在 Application Note on Shape-Based Matching 有详细的介绍
examples\\application guide\\shape matching\\hdevelop\\reuse model.dev 储存模型并重复使用
--->在 Application Note on Shape-Based Matching 有详细的介绍
examples\\hdevelop\\Applications\\FA\\cbm pipe wrench.dev 搜寻套筒扳手的二个组成要件 --->在 Quick Guide 有详细的介绍
examples\\hdevelop\\Applications\\FA\\pm multiple models.dev
Finds multiple different models in a single pass using shape-based matching 使用以形状为导向的匹配,来找寻各种不同的模形
examples\\hdevelop\\Applications\\FA\\pm world plane.dev
Recognizes planar objects using shape-based matching in perspectively distorted images 在透视变形的影像中使用以形状为导向的匹配来识别平面物体
examples\\hdevelop\\Applications\\OCR\\engraved.dev Segmenting and reading characters on a metal surface --->description here in the Quick Guide 在金属表面上分离和阅读字符 --->在 Quick Guide 有详细的介绍
examples\\hdevelop\\Applications\\OCR\\engravedt.dev Segmenting and training characters on a metal surface 在金属表面上分离和教导字符
examples\\hdevelop\\Matching\\Gray-Value-Based\\best match mg.dev
2
Finding the best match of a gray value template in a pyramid 在影像金字塔中找出最匹配的灰阶值样板位置
examples\\hdevelop\\Tools\\Geometry\\distance pc.dev Calculating the distance between a point and a contour 计算点到一条曲线间的距离
examples\\quick guide\\hdevelop\\measure metal part.dev 由最适线和圆来检查金属形状
examples\\quick guide\\hdevelop\\surface scratch.dev 由区域的二值化和形态学来检查平面上的刮痕 --->在 Quick Guide 有详细的介绍
2
3.5 机械
3.5.1 读取雕刻文字 范例:
examples\\hdevelop\\Applications\\OCR\\engraved.dev 这个范例的任务是在图 3.7 中,去读取在金属表面所雕刻的文字
(a)
(b)
图 3.7:(a)原始影像(b)读取的文字
这个任务要使用进阶的 blob 分析来解决: 若仅由选择较黑或较亮的像元作解析,并不能撷取出其字符,一个简单的分割反而产生伴随 噪声物体的片断字符。所以在分割动作之前,先使用灰阶值型态学处理,更可分离出正确的 字符。
gray_range_rect (Image, ImageResult, 7, 7) threshold (ImageResult, Region, 128, 255) connection (Region, ConnectedRegions)
select_shape (ConnectedRegions, SelectedRegions, 'area', 'and', 1000, 99999) sort_region (SelectedRegions, SortedRegions, 'first_point', 'true', 'column')
最后,执行底下的函数即完成读取的动作
read_ocr_class_mlp (Name+'.fnt', OCRHandle) for i := 1 to Number by 1
ObjectSelected := SortedRegions[i]
do_ocr_single_class_mlp (ObjectSelected, ImageResult, OCRHandle, 1, Class, Confidence) endfor
clear_ocr_class_mlp (OCRHandle)
2
3.5.2 检视工具的轮廓
范例:examples\\hdevelop\\Applications\\FA\\circles.dev
这个范例的任务是在图 3.8 中检视工具的轮廓
图 3.8:工具轮廓的最适圆 因为撷取次像元精度的轮廓是很费
时的,所以我们会在第一个步骤中先粗略的找寻出边缘: 1.首先我们先使用二值化的操作来撷取测量的物体。 2.之后将物体的 region 转变成到它的边界。 3.最后再删去在影像的边线像元。
fast_threshold (Image, Region, 0, 120, 7) boundary (Region, RegionBorder, 'inner')
clip_region_rel (RegionBorder, RegionClipped, 5, 5, 5, 5)
接下来使用一个较小的 region 去 close 物体的边缘,再使这个 region 的边界(即边缘)扩张变成 另一个 ROI。下一步我们将影像 domain 缩小,只撷取其边缘部分。现在,呼叫次像元精度 的边缘撷取函数,再将轮廓线切割成为平直的线和圆弧的线。 dilation_circle (RegionClipped, RegionDilation, 2.5) reduce_domain (Image, RegionDilation, ImageReduced) edges_sub_pix (ImageReduced, Edges, 'lanser2', 0.5, 40, 60)
segment_contours_xld (Edges, ContoursSplit, 'lines_circles', 5, 4, 3)
为了求出最适切的圆弧,要设定相关参数。为了肉眼检视的目的,最后将结果和影像显示在 一起。
2
get_contour_global_attrib_xld (ObjectSelected, 'cont_approx', Attrib) if (Attrib > 0)
fit_circle_contour_xld (ObjectSelected, 'ahuber', -1, 2, 0, 3, 2, Row,Column, Radius, StartPhi, EndPhi, PointOrder)
gen_ellipse_contour_xld (ContEllipse, Row, Column, 0, Radius, Radius, 0,rad(360), 'positive', 1.0) dev_display (ContEllipse) endif
2
3.5.3 在不同的状态下找出套筒板手
范例:examples\\hdevelop\\Applications\\FA\\cbm pipe wrench.dev
这个范例的任务是以四个预先定义好的 ROI 为基础下,去找出套筒板手(见图 3.9)。四个 ROI 中有两组相对位置固定的 ROI,两 ROI 组间的相对位置是不固定的。
(a)
(b)
图 3.9:(a)在模型影像中依构造指定其 ROI;(b)在其它状态中找寻套筒板手
展示同一系统中多个影像来教导相关部份的移动。
read_image (ModelImage, 'pipe_wrench/pipe_wrench_model') gen_rectangle2 (InitialComponentRegions, 212, 233, 0.62, 167, 29) gen_rectangle2 (Rectangle2, 298, 363, 1.17, 162, 34) gen_rectangle2 (Rectangle3, 63, 444, -0.26, 50, 27) gen_rectangle2 (Rectangle4, 120, 473, 0, 33, 20)
InitialComponentRegions := [InitialComponentRegions,Rectangle2] InitialComponentRegions := [InitialComponentRegions,Rectangle3] InitialComponentRegions := [InitialComponentRegions,Rectangle4] for i := 1 to 4 by 1
read_image (TrainingImage, 'pipe_wrench/pipe_wrench_training_'+i) TrainingImages := [TrainingImages,TrainingImage] endfor
train_model_components(ModelImage,InitialComponentRegions,TrainingImages, ModelComponents, 22, 60, 30, 0.65, -1, -1, rad(60),'speed', 'rigidity', 0.2,0.4, ComponentTrainingID)
它们的构造和关系会由底下的函数显示:
get_training_components (ModelComponents, ComponentTrainingID, 'model_components', 'model_image', 'false', RowRef, ColumnRef, AngleRef, ScoreRef)
dev_display (ModelComponents)
get_component_relations (Relations, ComponentTrainingID, i, 'model_image',
2
Row, Column, Phi, Length1, Length2, AngleStart, AngleExtent) dev_display (Relations)
根据教导,实际的构造模型会被产生出。其构造的关系会被表现在树状结构中。
create_trained_component_model (ComponentTrainingID, rad(-90), rad(180), 10, 0.6, 4, 0, 'none', 'use_polarity', 'false', ComponentModelID, RootRanking)
get_component_model_tree (Tree, Relations, ComponentModelID, RootRanking, 'model_image', StartNode, EndNode, Row, Column, Phi, Length1, Length2, AngleStart, AngleExtent) dev_display (ModelImage) dev_display (Tree) dev_display (Relations)
最后,我们用测试的影像来找寻套筒板手;在每个影像中,我们可以看到模型的轮廓被覆盖 着、转动着并且套筒板手打开的角度也有所不同。
find_component_model (SearchImage, ComponentModelID, RootRanking, rad(-90), rad(180), 0, 0, 1, 'stop_search', 'prune_branch', 'none',
0.6, 'interpolation', 0, 0.7, ModelStart, ModelEnd, Score, RowComp, ColumnComp, AngleComp, ScoreComp, ModelComp) dev_display (SearchImage) NumFound := |ModelStart| if (NumFound)
get_found_component_model (FoundComponents, ComponentModelID, ModelStart, ModelEnd, RowComp, ColumnComp, AngleComp, ScoreComp, ModelComp, 0, 'false', RowCompInst, ColumnCompInst, AngleCompInst, ScoreCompInst) dev_display (FoundComponents) endif
3.5.4 其它的范例
HDevelop
examples\\application guide\\shape matching\\hdevelop\\multiple models.dev 同时寻找二个不同形状的物体
--->在 Application Note on Shape-Based Matching 有详细的介绍
examples\\application guide\\shape matching\\hdevelop\\multiple objects.dev 搜寻安全环的例子
--->在 Application Note on Shape-Based Matching 有详细的介绍
examples\\application guide\\shape matching\\hdevelop\\multiple scales.dev 搜寻不同尺寸的螺帽
--->在 Application Note on Shape-Based Matching 有详细的介绍
2
examples\\application guide\\shape matching\\hdevelop\\reuse model.dev 储存并重复使用一个模形
--->在 Application Note on Shape-Based Matching 有详细的介绍
examples\\hdevelop\\Applications\\Measure\\measure arc.dev 沿着圆形弧度测量物体的宽
--->在 Quick Guide 有详细的介绍
examples\\hdevelop\\Applications\\OCR\\engravedt.dev Segmenting and training characters on a metal surface 在金属表面上分离和教导字符
3
3.6 航空摄影测量和遥感
3.6.1 从红外线影像撷取森林的特征
范例:examples\\hdevelop\\Applications\\Aerial\\forest.dev
这个范例的任务是在图 3.10 中,去检查在红外线影像中不同的物体分类:树、草地、道路。
(a) (b) (c) 图 310:(a)原始影像;(b)撷取树和草地(c)撷取道路
这张影像数据是属于红外线假色影像,由于它特别的颜色,因此,可容易的撷取出道路的部
份。
read_image (Forest, 'forest_air1')
decompose3 (Forest, Red, Green, Blue) threshold (Blue, BlueBright, 80, 255)
connection (BlueBright, BlueBrightConnection)
select_shape (BlueBrightConnection, Path, 'area', 'and', 100, 100000000)
在红色的 channel 中,根据其光的强度和最小的尺寸之下,使山毛榉树被分离出来。
threshold (Red, RedBright, 120, 255)
connection (RedBright, RedBrightConnection)
select_shape (RedBrightConnection, RedBrightBig, 'area', 'and', 1500, 10000000)
closing_circle (RedBrightBig, RedBrightClosing, 7.5)
opening_circle (RedBrightClosing, RedBrightOpening, 9.5) connection (RedBrightOpening, RedBrightOpeningConnection)
select_shape (RedBrightOpeningConnection, BeechBig, 'area', 'and', 1000, 100000000)
select_gray (BeechBig, Blue, Beech, 'mean', 'and', 0, 59)
3
草地有着相似的光谱属性,但稍稍较为明亮。
union1 (Beech, BeechUnion)
complement (BeechUnion, NotBeech)
difference (NotBeech, Path, NotBeechNotPath)
reduce_domain (Red, NotBeechNotPath, NotBeechNotPathRed) threshold (NotBeechNotPathRed, BrightRest, 150, 255) connection (BrightRest, BrightRestConnection)
select_shape (BrightRestConnection, Meadow, 'area', 'and', 500, 1000000)
先使用 watershed 方法,再由二值化中清除阴暗区域,来撷取结球果的树,
union2 (Path, RedBrightClosing, BeechPath) smooth_image (Red, RedGauss, 'gauss', 4.0) invert_image (RedGauss, Invert)
watersheds (Invert, SpruceRed, Watersheds)
select_shape (SpruceRed, SpruceRedLarge, 'area', 'and', 100, 5000)
select_gray (SpruceRedLarge, Red, SpruceRedInitial, 'max', 'and', 100, 200) LocalThresh := []
NumSpruce := |SpruceRedInitial| for i := 1 to NumSpruce by 1
SingleSpruce := SpruceRedInitial[i]
min_max_gray (SingleSpruce, Red, 50, Min, Max, Range) reduce_domain (Red, SingleSpruce, SingleSpruceRed)
threshold (SingleSpruceRed, SingleSpruceBright, Min, 255) connection (SingleSpruceBright, SingleSpruceBrightCon)
select_shape_std (SingleSpruceBrightCon, MaxAreaSpruce, 'max_area', 70) LocalThresh := [MaxAreaSpruce,LocalThresh] endfor
opening_circle (LocalThresh, FinalSpruce, 1.5)
3
3.6.2 在彩色影像中分离物体
范例:examples\\hdevelop\\Filter\\Edges\\edges color.dev 这个范例的任务是在图 3.11 中分割彩色影像。 这个例子是显
示在 multi-channel 中过滤边缘的可能性。
首先,从彩色影像中取得灰阶值影像,从这我们可以看出某些物体的边缘不能被看到了。 例如,足球场(绿色的)和周围的跑道(红色的)不能被识别出。
图 3.11:(a)原始影像(b)撷取彩色边缘覆盖在彩色影像上(c) 撷取灰阶值边缘覆盖在灰阶值影 像上
read_image (Image, 'olympic_stadium') rgb1_to_gray (Image, GrayImage)
应用彩色边缘的过滤并且显示其边缘线。假使你比较这二种边缘的不同就可以很容易的了解 其差异。
edges_color (Image, ImaAmp, ImaDir, 'canny', 1, 'none', -1, -1)
edges_image (GrayImage, ImaAmpGray, ImaDirGray, 'canny', 1, 'none', -1, -1)
最后,从彩色和灰阶影像撷取出边缘线,并且覆盖在原始的影像中。
edges_color (Image, ImaAmpHyst, ImaDirHyst, 'canny', 1, 'nms', 20, 40) threshold (ImaAmpHyst, RegionColor, 1, 255) skeleton (RegionColor, EdgesColor) dev_display (Image)
dev_display (EdgesColor) stop ()
edges_image (GrayImage, ImaAmpGrayHyst, ImaDirGrayHyst, 'canny', 1, 'nms',20, 40) threshold (ImaAmpGrayHyst, RegionGray, 1, 255)
3
skeleton (RegionGray, EdgesGray) dev_display (GrayImage) dev_display (EdgesGray)
3
3.6.3 撷取道路
范例:examples\\hdevelop\\Applications\\Aerial\\roads.dev
这个范例的任务是在图 3.12 的空照影像中去撷取道路。程序开始首先在放大尺寸的影像中撷 取 lines。而这道路本身就是一个很好的线形。
图 3.12:(a)原始影像;(b)缩放影像的部份;(c)撷取道路
threshold (Mreut43, Bright, 160, 255)
reduce_domain (Mreut43, Bright, Mreut43Bright)
lines_gauss (Mreut43Bright, RoadCenters, 1.2, 5, 14, 'light', 'true', 'true', 'true')
为了消除一些可能的错误,在较大的比例尺影像中撷取边缘进行计算。在道路撷取上,我们 假定它是由二个平行的边缘所组成,而在这二并行线之间即为道路部份。使用 contour processing 可以一步一步的找出较为精确的结果。
edges_image (Part, PartAmp, PartDir, 'mderiche2', 0.3, 'nms', 20, 40) threshold (PartAmp, EdgeRegion, 1, 255)
clip_region (EdgeRegion, ClippedEdges, 2, 2, PartWidth - 3, PartHeight - 3) skeleton (ClippedEdges, EdgeSkeleton)
gen_contours_skeleton_xld (EdgeSkeleton, RoadEdges, 1, 'filter') gen_polygons_xld (RoadEdges, RoadEdgePolygons, 'ramer', 2)
gen_parallels_xld (RoadEdgePolygons, ParallelRoadEdges, 10, 30, 0.15, 'true')
mod_parallels_xld (ParallelRoadEdges, Part, ModParallelRoadEdges, ExtParallelRoadEdges, 0.3, 160, 220, 10)
combine_roads_xld (RoadEdgePolygons, ModParallelRoadEdges,ExtParallelRoadEdges, RoadCenterPolygons, RoadSides, rad(40),rad(20), 40, 40)
3
3.6.4 其它的范例 HDevelop
examples\\hdevelop\\Applications\\Aerial\\dem.dev 从一个数字高度模型来撷取出物体的高
examples\\hdevelop\\Applications\\Aerial\\dem trees.dev Extraction of trees using texture and a digital elevation model 使用纹理和数字高度模型来撷取树
examples\\hdevelop\\Applications\\Aerial\\high.dev 用二种不同的方法来撷取物体的高
examples\\hdevelop\\Applications\\Aerial\exture.dev 找出纹理区域(树和灌木)
examples\\hdevelop\\Manuals\\HDevelop\\dtm.dev 从一个数字高度模型来撷取出物体的高
3
3.7 印刷
3.7.1 读取条形码
范例: examples\\hdevelop\\Applications\\Barcode\\EAN13AddOn5.dev
这个范例的任务是去读取条形码,见图 3.13。
图 3.13:解读条形码
这个例子显示出条形码(甚至是复合的条形码),能够使用 HALCON 容易的去解读。 首先,必需区分条形码的类型
gen_1d_bar_code_descr ('EAN 13 Add-On 5', 13, 13, BarCodeDescr)
从档案读取影像之后,条形码的撷取器会被呼叫。这项作业的结果,即每个元素的宽度,之后 再将结果传给解读的作业。
read_image (image, 'barcode/ean13addon5/ean13addon5'+(i$'.2'))
find_1d_bar_code (image, CodeRegion, BarCodeDescr, 'dilation_factor', 2, BarcodeFound, BarCode, Orientation)
decode_1d_bar_code (BarCode, BarCodeDescr, Characters, Reference, IsCorrect)
3.7.2 其它的范例
HDevelop
examples\\hdevelop\\Applications\\OCR\\stamp catalogue.dev 在杂乱的页面上分离和群集字符
examples\\hdevelop\\Applications\\OCV\\adaption ocv.dev 从报告的字符特性分析改变的影向
examples\\hdevelop\\Applications\\OCV\\print quality.dev 在不同的影像中显示字母 A 的特性
3
examples\\hdevelop\\Tools\\OCV\\write ocv.dev 写入 OCV 数据到档案中(并再读取出来)
3.8 橡胶、合成纤维材料、金属薄片
3.8.1 Checking a Boundary for Fins
范例: examples\\hdevelop\\Applications\\FA\\fin.dev
这个范例的任务是要检查塑料零件的外部边界。在这个案中,某些物体在一个应为无缺点的 部份却有突起物,这是不被允许的(见图 3.14)。
图 3.14:撷取边界的突起物 首先程序会先撷取塑料零件,然
后利用 complement 方法去撷取背景的 region(边界的突起物 如同背景 region 的凹陷) bin_threshold (Fin, Dark)
difference (Fin, Dark, Background)
在背景 region 的这个凹陷,使用型态学的方法 close 将它填满
closing_circle (Background, ClosedBackground, 250)
3
在 close 之后的 region 和原始的 region 之间,有一个重要的不同就是缺陷的产生。
difference (ClosedBackground, Background, RegionDifference) opening_rectangle1 (RegionDifference, FinRegion, 5, 5)
3.8.2 其它的范例 HDevelop
examples\\hdevelop\\Applications\\FA\\hull.dev 检查注射模型的喷嘴
3
3.9 半导体
3.9.1 Bonding Balls
范例: examples\\hdevelop\\Applications\\FA\\ball.dev
这个范例的任务是要检查图 3.15 中 ball bonds 的直径。
图 3.15:测量 ball bonds 的直
径
为了找出 ball bonds 需要经过二个步骤:首先,分离比较明亮的区域以找出 die,然后将找出 来的结果,当成一个输入项,转换成最小的平行矩形。 threshold (Bond, Bright, 100, 255) shape_trans (Bright, Die, 'rectangle2')
现在,处理的重点是在 die 里面的 region,这我们使用 reduce_domain 将原始影像和经过 shape_trans 的影像相减,产生一个只含 ROI 的原始影像。之后在这个 ROI,程序会检查较暗 的区域,这个较黑的区域是金属接线的地方 reduce_domain (Bond, Die, DieGrey) threshold (DieGrey, Wires, 0, 50)
fill_up_shape (Wires, WiresFilled, 'area', 1, 100)
4
由 opening_circle 指令来移除不符的结构,然后把物体抽出变成一个独立的物的之后再用 select_shape 找出圆形物体,并且排列物体,就能撷取想要的特征了。
opening_circle (WiresFilled, Balls, 15.5) connection (Balls, SingleBalls)
select_shape (SingleBalls, IntermediateBalls, 'circularity', 'and', 0.85, 1.0)
sort_region (IntermediateBalls, FinalBalls, 'first_point', 'true', 'column') smallest_circle (FinalBalls, Row, Column, Radius) 3.9.2 使用 Fuzzy 测量来检查 IC
范例: examples\\hdevelop\\Applications\\Measure\\fuzzy measure pin.dev
这个范例的任务是检查在图 3.16 中 IC 的接脚的宽度和距离。
图 3.16:测量接脚的宽度和距离
在这个范例中照明的条件是相当的困难,因为照明会很明显的影响到每个接脚的四个边。因 此可使用 Fuzzy 的方式来限制正确的接脚数目。
4
gen_measure_rectangle2 (305.5, 375.5, 0.982, 167, 7.5, Width, Height, 'nearest_neighbor', MeasureHandle1)
create_funct_1d_pairs ([0.0, 0.3], [1.0,0.0], FuzzyAbsSizeDiffFunction) set_fuzzy_measure_norm_pair (MeasureHandle1, 11.0, 'size_abs_diff', FuzzyAbsSizeDiffFunction)
fuzzy_measure_pairs (Image, MeasureHandle1, 1, 30, 0.5, 'positive',
RowEdgeFirst1, ColumnEdgeFirst1, AmplitudeFirst1, RowEdgeSecond1, ColumnEdgeSecond1, AmplitudeSecond1, RowEdgeMiddle1,
ColumnEdgeMiddle1, FuzzyScore1, IntraDistance1, InterDistance1)
3.9.3 测量移动中 IC 的接脚
范例: examples\\hdevelop\\Applications\\FA\\pm measure board.dev
这个范例的任务是测量芯片接脚的位置(见图 3.17),因为芯片可以用不同的位置和角度下出 现,所以在测量 ROI 时必需先使用校准。
(a) (b)
图 3.17:(a)测量 ROI 的模型影像(b)对已校准的 ROI 上测量其接脚
在这个案中,经由以型状导向的匹配,搜寻芯片上的印刷字完成定位。
gen_rectangle1 (Rectangle, Row1, Column1, Row2, Column2) reduce_domain (Image, Rectangle, ImageReduced)
create_shape_model (ImageReduced, 4, 0, rad(360), rad(1), 'none', 'use_polarity', 30, 10, ModelID)
找到印刷字之后,就可以知道测量的 ROI 位置与印刷字的位置间的相对关系。
find_shape_model (ImageCheck, ModelID, 0, rad(360), 0.8, 1, 0.5, 'interpolation', 4, 0.9, RowCheck, ColumnCheck, AngleCheck, Score) hom_mat2d_identity (HomMat2DIdentity)
hom_mat2d_translate (HomMat2DIdentity, RowCheck, ColumnCheck, HomMat2DTranslate)
hom_mat2d_rotate (HomMat2DTranslate, AngleCheck, RowCheck, ColumnCheck,
4
HomMat2DRotate)
affine_trans_pixel (HomMat2DRotate, Rect1Row, Rect1Col, Rect1RowCheck, Rect1ColCheck)
然后,产生一个测量的工具并进行量测
gen_measure_rectangle2 (Rect1RowCheck, Rect1ColCheck, AngleCheck, RectLength1, RectLength2, Width, Height, 'bilinear', MeasureHandle1) measure_pairs (ImageCheck, MeasureHandle1, 2, 90, 'positive', 'all',
RowEdgeFirst1, ColumnEdgeFirst1, AmplitudeFirst1, RowEdgeSecond1, ColumnEdgeSecond1, AmplitudeSecond1, IntraDistance1, InterDistance1) 3.9.4 产生一个 mosaic 影像
范例: examples\\hdevelop\\Tools\\2D-Transformations\\gen projective mosaic.dev
这个范例的任务是在图 3.18 产生一个长条型的电路板影像。若使用标准的影像大小,则部份 的影像会被清掉,而解决的方法就是从各种不同的位置来撷取影像,以产生 mosaic 影像。
图 3.18:从若干重迭的影像产生一个 mosaic 影像 将电路板各部份重迭的
影像输入到程序中;第一个步骤,在每张影像撷取其特征部份。这些
部份会被输入到以特征点为匹配的输入中。之后的每个步骤,相继的两张影像可以配对起 来。将这张影像配对到下张影像直到结束,就是这项处理的结果。
4
points_foerstner (ImageF, 1, 2, 3, 200, 0.3, 'gauss', 'false',
RowJunctionsF, ColJunctionsF, CoRRJunctionsF, CoRCJunctionsF,
CoCCJunctionsF, RowAreaF, ColAreaF, CoRRAreaF, CoRCAreaF, CoCCAreaF) points_foerstner (ImageT, 1, 2, 3, 200, 0.3, 'gauss', 'false',
RowJunctionsT, ColJunctionsT, CoRRJunctionsT, CoRCJunctionsT,
CoCCJunctionsT, RowAreaT, ColAreaT, CoRRAreaT, CoRCAreaT, CoCCAreaT) proj_match_points_ransac (ImageF, ImageT, RowJunctionsF, ColJunctionsF, RowJunctionsT, ColJunctionsT, 'ncc', 21, 0, 0, 480, 640, 0, 0.5, 'gold_standard', 1, 4364537, ProjMatrix, Points1, Points2) ProjMatrices := [ProjMatrices,ProjMatrix]
将这些影像收集起来,最后建构一个单一高解析影像的完整 PCB
gen_projective_mosaic (Images, MosaicImage, 2, From, To, ProjMatrices, 'default', 'false', MosaicMatrices2D)
4
3.9.5.利用颜色找出电路板上的组件
范例:examples\\hdevelop\\Applications\\FA\\ic.dev
这个范例的任务是在图 3.19 中,去找出电路板上所有的组件
图 3.19(a)原始影像(b)撷取 IC、电阻与电容
输入的数据是一张有颜色的影像,它不同的颜色找出组件,像是电容或电阻:使用 color space 的转换,利用不同颜色的值找出相对应的组件。接下来的程序会去撷取电阻、电容, 其撷取方式,用相同的方法进行。
decompose3 (Image, Red, Green, Blue)
trans_from_rgb (Red, Green, Blue, Hue, Saturation, Intensity, 'hsv') threshold (Saturation, Colored, 100, 255) reduce_domain (Hue, Colored, HueColored) threshold (HueColored, Red, 10, 19) connection (Red, RedConnect)
select_shape (RedConnect, RedLarge, 'area', 'and', 150.000000, 99999.000000) shape_trans (RedLarge, Resistors, 'rectangle2')
IC 的撷取是较困难的,因为在这个步骤中明亮的部份不允许一个简单的二值化处理,所以 另一个替代的方法是,先选择较暗的区域,然后使用 dilation 结合。
threshold (Intensity, Dark, 0, 50)
dilation_rectangle1 (Dark, DarkDilation, 14, 14) connection (DarkDilation, ICLarge)
之后,重复的进行分离的动作,直到相连接的组件分离为止。
4
add_channels (ICLarge, Intensity, ICLargeGray) threshold (ICLargeGray, ICDark, 0, 50) shape_trans (ICDark, IC, 'rectangle2')
为了找出接脚,在每一个 IC 的左边和右边产生了许多个较小的 ROI
dilation_rectangle1 (IC, ICDilation, 5, 1) difference (ICDilation, IC, SearchSpace)
dilation_rectangle1 (SearchSpace, SearchSpaceDilation, 14, 1) union1 (SearchSpaceDilation, SearchSpaceUnion)
在这些区域中附近的亮点会被发现
reduce_domain (Intensity, SearchSpaceUnion, SearchGray) mean_image (SearchGray, SearchMean, 15, 15)
dyn_threshold (SearchGray, SearchMean, PinsRaw, 5.000000, 'light') connection (PinsRaw, PinsConnect) fill_up (PinsConnect, PinsFilled)
select_shape (PinsFilled, Pins, 'area', 'and', 10, 100)
4
3.9.6 其它的范例
HDevelop
examples\\application guide\\3d machine vision\\hdevelop\\ height above reference plane from stereo.dev 从双像立体视觉中,使用高度信息撷取芯片
--->在 Application Note on 3D Machine Vision 中有详细的描述
examples\\application guide\\3d machine vision\\hdevelop\\mosaicking.dev 使用 mosaick 来合并 BGA 的局部影像成为一个较大的影像 --->在 Application Note on 3D Machine Vision 有详细的描述
examples\\application guide\\shape matching\\hdevelop\\ first example shape matching.dev 介绍 HALCON 型状导向的匹配
--->在 Application Note on Shape-Based Matching 有详细的描述
examples\\application guide\\shape matching\\hdevelop\\process shape model.dev 经由更改显示型状模型的结果产生另一个 ROI 的模型
--->在 Application Note on Shape-Based Matching 有详细的描述
examples\\application guide\\shape matching\\hdevelop\\synthetic circle.dev 使用合成的模型(圆)来搜寻电路板上的电容
--->在 Application Note on Shape-Based Matching 有详细的描述
examples\\hdevelop\\Applications\\FA\\ball seq.dev 检视 ball bonding(复合影像)
examples\\hdevelop\\Applications\\FA\\board.dev 发现遗失的杆接点
examples\\hdevelop\\Applications\\FA\\cbm dip switch.dev 找寻 dip switches 并使用以组件导向的匹配来测试它的状态 --->在 Quick Guide 有详细的描述
examples\\hdevelop\\Applications\\Measure\\measure pin.dev 测量 IC 的接脚
--->在 Quick Guide 有详细的描述
examples\\hdevelop\\Applications\\Stereo\\board components.dev Segments board components by height using binocular stereo --->在 Quick Guide 有详细的描述
examples\\hdevelop\\Manuals\\HDevelop\\ball.dev 检查 bonding of balls
--->在 HDevelop User’s Manual 有详细的描述
examples\\hdevelop\\Manuals\\HDevelop\\ic.dev 结合不同的分割方法
4
--->在 HDevelop User’s Manual 有详细的描述
examples\\hdevelop\\Matching\\Component-Based\\cbm modules simple.dev 在电路板中使用组件导向的匹配来找寻一个模型 --->在 Quick Guide 有详细的描述
examples\\hdevelop\\Matching\\Component-Based\\cbm sbm.dev 比较组件导向的匹配和型状导向的匹配
examples\\hdevelop\\Morphology\\Gray-Values\\pcb inspection.dev 使用灰阶值型态学在 PCB 上找寻缺陷
examples\\hdevelop\\Regions\\Transformations\\distance transform.dev 检查相似的电路板之缺陷
examples\\hdevelop\\Segmentation\\Classification\\class 2dim sup.dev 使用 2D 像元来分割影像
examples\\hdevelop\\Segmentation\\Classification\\class ndim box.dev 使用 hyper-cuboids 分类像元
examples\\hdevelop\\Segmentation\\Classification\\class ndim norm.dev 使用 hyper-spheres 分割像元
examples\\hdevelop\\XLD\\Transformation\ contours xld.dev 连接原本相连的线之片断
C++
examples\\cpp\\source\\fuzzy measure pin.cpp 使用 fuzzy 量测来量 IC 的接脚
examples\\mfc\\Matching\\Matching.cpp
使用 HALCON/C++和 MFC 找寻 IC,并产生 HALCON 窗口
examples\\mfc\\MatchingCOM\\Matching.cpp 使用 HALCON/COM 和 MFC 找寻 IC
examples\\mfc\\MatchingExtWin\\Matching.cpp
使用 HALCON/C++和 MFC 找寻 IC,并显示在现存的窗口中
examples\\motif\\Matching\\matching.cpp 使用 HALCON/C++和 Motif 来找出 IC
Visual Basic
examples\\vb\\Tools\\Matching\\matching.vbp 找出电路板上的 IC 并测量接脚的距离
4
examples\\vb\\Tools\\Measure\\measure.vbp 用参数的 interactive control 测量接脚
C#
examples\\c#\\Matching\\Matching.csproj 找出电路板上的 IC 并测量接脚的距离
C
examples\\c\\example multithreaded1.c 在 Parallel HALCON 下使用多执行绪
Delphi
examples\\delphi\\Matching\\matching.dpr 找出电路板上的IC并测量接脚的距离
4
因篇幅问题不能全部显示,请点此查看更多更全内容