影像处理:NI Vision VIs
前言
在2-2这个章节要来介绍如何使用NI Vision API来完成影像处理任务,从获取影像开始到得到我们要的结果,我们都能利用NI Vision API来完成,那NI Vision API在哪裡呢?首先我们要打开
labview,然后开启一个新的Block Diagram,如果我们在安装LabVIEW的时候有安装到NI Vision Development Module,那我们就能在Block Diagram的Func
tion选单中找到一个Vision and Motion的类别,在这个类别裡面就会有我们要使用的NI Vision API,如下图2-29所示:
图2-29 NI Vision API
在图2-29中,作者我未来会介绍到的部分,同时也是我们平常比较常会使用到的部分有:NI-IMAQdx、Vision Utilities、Image Processing和Machine Vision。从LabVIEW Context Help视窗的说明内,我们可以约略得知这些类别下的function所提供的功能:
1. NI-IMAQdx:建立撷取影像的系统。
2. Vision Utilities:建立影像、操作影像。
3. Image Processing:分析、过滤、处理影像。
4. Machine Vision:透过影像进行量测。
通常一个影像处理程式的撰写大致可以简略分为以下步骤:
1. 创建影像记忆体空间
2. 获得影像,并将其放入步骤1创建的记忆体空间
3. 进行需要的影像处理
4. 标示、输出影像处理的结果
5. 释放影像记忆体空间
在接下来的章节,作者我会带领大家完成一个简单的影像处理程式,从创建影像暂存记忆体开始,到获得影像、处理影像,再到最终得到我们要的结果,各位準备好了吗?快快打开LabVIEW,我们现在就开始吧!
2-2-2 ImageBuffer
要处理影像之前,首先要获得影像,而在获得影像之前,我们需要先创建一个记忆体空间来暂存我们即将获得的影像,而这个用来暂存影像的记忆体空间我们可以称唿它为Image Buffer。那要如何创建这个记忆体空间呢?大家还记得第一章(下)的图1-37吗?没错!图中这个IMAQ Create的function就是拿来创建影像暂存的记忆体空间用的,透过这个function我们可以去定义这个记忆体空间要储存的影像类型,预设是灰阶(unsigned byte),同时作者这边会建议要给这个记忆体空间一个有意义的名字,不要用预设的untitled,这样在使用到很多Image Buffer的时候程式的可读性会比较高;而它隔壁的好邻居IMAQ Dispose这个function则是用来释放这个记忆体空间用的,大家在使用完这个影像暂存的记忆体空间后,务必要养成将它释放的好习惯,否则若哪天一不小心,就有可能会遇到记忆体不足LabVIEW当掉或是异常关闭的状况喔。
图1-37 IMAQ Create与Dispose
元件
2-2-3 获得影像
程式中要使用的影像,其来源有两种,一为用相机撷取,二为载入现存在电脑中的影像档。
首先来帮大家复习一下,在1-2-2节中,我们曾经提及如何使用NI Vision API中的Low Level Function操作相机来进行取像,还记得下面的图1-39吗?
图1-39 Low Level 取像元件程式码
步骤说明:
1. 指定开启相机名称,从「IMAQ Session」中选择对应的相机名称
2. 设定相机取像模式为「连续」,Image Buffer设为「3」
3. 开始取像
4. 任何由外部取得的影像,都需透过IMAQ建立一组记忆体空间来储存,由于取像来源是彩色相机,每一张彩色(RGB)影像需要3*8bit的空间来储存,所以「Image Type」要选择「RGB U32」
5. 进入While迴圈后,会不断将影像覆盖到记忆体区内,此时将影像接到Display Image即可在人机介面观察到影像,直到按下「Stop」或Error产生时才会跳出迴圈
6. 停止取像
7. 解除相机设定
8. 结束指定名称的相机作业
9. 清空储存影像的记忆体空间
如果是要载入电脑裡的图档来进行处理的话,我们会需要用到下图2-30中的IMAQ Load Image Dialog和IMAQ ReadFile这两个function,範例程式码如下图2-31所示。
图2-30 Load Image function
图2-31 Load Image from Image File範例程式码
现在我们成功地将影像载入程式中了,在接下来的章节中,我们将使用NI Vision API来处理之前在2-1中有练习过的範例:Spark Plug Inspection。
2-2-4 使用NI Vision API完成Spark Plug Inspection範例
还记得Spark Plug Inspection这个範例要做什么吗?
1. 量测Spark Plug Base的宽度
2. 量测Electrodes的间距
在撰写程式码之前我们先简单规划一下需要撰写的功能和步骤:
1. 创建一个灰阶的Image Buffer
2. 将Spark Plug的影像档载入步骤1所创建的记忆体空间
3. 使用NI Vision API的function去找到Spark Plug Base的两个量测点
4. 使用NI Vision API的function去找到Electrodes的两个量测点
5. 使用NI Vision API的function进行点和点之间的距离量测
6. 得到量测结果后释放记忆体空间
首先麻烦大家先完成之前图2-31的程式码,因为图2-31的程式码其实就是上述的步骤1和步骤2,大家应该早就发现了吧?
完成图2-31的程式码之后,我们要在NI Vision API内选择适合的function来完成步骤3和步骤4,基本上我们现在要做的事情就是找点,所以我们要找的function毫无疑问地会在Machine Vision这个类别底下,那所谓的找点其实就是要Find Edge,因此我们接着点选Caliper这个子类别,然后就会看到我们要找的Edge Tool了,详细位置如下图2-32所示。
图2-32 Find Edge Tools
在图2-32中我们可以看到能够用来在一条线上Find Edge的function有两个:
IMAQ Simple Edge Tool 和IMAQ Advanced Edge Tool,基本上这两者都可以达到我们的目的,但是在使用方式上有些不同,IMAQ Simple Edge Tool 的座标设定是使用Pixel Coordinates,在边界筛选的Threshold Parameters设定上也比较简略,而IMAQ Advanced Edge Tool 的座标设定是使用ROI,在边界筛选的Edge Options设定上则需要比较精确的设定,那在这个範例中我们选择使用IMAQ Simple Edge Tool 来达成我们的目的,在未来的章节会再跟各位详细介绍ROI和Edge Options中各个参数所代表的意义。那么我们现在把IMAQ Simple Edge Tool 加入程式码改写,完成之后我们的程式码应该会如下图2-33所示。
图2-33 Simple Find Edge Code
图2-33中,Threshold Parameters设定的部分在大多数的应用上都是要因应图的实际表现,去设定我们认为最适合的值,在这个案例中使用预设的设定就可以达成我们的需求,所以保持预设的设定;在Pixel Coordinates设定的部分,因为我们是要量测物体的宽度,所以必须画一条横跨量测物的线,Start Point座标和End Point座标是用Array传入;Process的部分因为我们画的是横跨量测物的线,所以要找的是第一点和最终点,因此最后输出的Edges Coordinates Array中会有两个点;Sub-Pixel Accuracy设定为True时,function内部的运算会将边界点附近像点的值也纳入计算,故输出结果会有小数位,提供更加精确的结果。
利用IMAQ Simple Edge Tool找到点之后,接着我们要在NI Vision API内选择适合的function来完成步骤5,量测点与点之间的距离,既然是要进行量测,不用怀疑,我们要的function一定也是在Machine Vision这个类别底下,现在有没有看到一个Analytic Geometry的子类别,一看就觉得跟我们要找的function有关係,再往下找,果不其然就看到了一个IMAQ Point Distances的function,详细位置如下图2-34所示。
图2-34 IMAQ Point Distances Tool
找到它之后马上把它加入程式中,然后我们就会看到如下图2-35的程式码。
图2-35 Inspect Point Distances Tools
IMAQ Point Distances这个function它可以一次量测多个点之间的距离,所以我们会看到它的输出Distances是一个array,在这个案例中因为我们只有传入两个点,所以array中只会有一个element,直接将它取出就是我们要的结果了。
取出结果之后,大家千万不要忘记我们最后还有一个步骤就是要释放影像暂存记忆体的空间,作者我刚才也差点忘记了!让我们加入IMAQ Dispose 这个function来完成释放记忆体的动作,我们可以选择接上我们要释放的Image Buffer或是在All Images? (No)这个接点上接上True,释放之前创建的所有Image Buffer,最后完成的程式码会如下图2-36所示。
图2-36 Spark Plug Inspection Code
恭喜大家,我们成功利用NI Vision API完成了一个简单的案例啰!执行这一支程式所需要的图片Sparkplug1.jpg可以在下面这个路径找到:C:Program Files (x86)National InstrumentsVision Assistantsolutionsautomotivesparkplug
34