在NI范例查找器中打开工具包和模块>视觉>函数,双击第一个函数2D Barcode.vi,如图1所示:
图1 NI Vision 2D Barcode
打开此二维条码后,前面如图2所示:
图2 NI Vision 2D Barcode.vi前面板
前面板的控件主要有Barcode Type条码类型、Use Options(if available)使用选项(如果有效)、Grade Data Matrix code分级数据矩阵代码、Delay(ms)延时、Results结果、Image图像显示、Stop停止。其中条码类型是用于区分不同的二维条码,如数据矩阵、PDF417、QR二维条码等;使用选项,是可以对条码进行一些预处理,可以加速条码的识别;分级数据矩阵代码,AIM目标分级,可以将条码进行分级,以提示条码的好坏,具体可以参看NI Vision Concepts.chm帮助手册。结果界面主要包含了条码类型、条码数据、条码读取耗时、目标分级报告,另外一个显示就是图像了。下面我们先运行一下程序看看其效果。
图3 读取数据矩阵-使用选项-无分级
图4读取数据矩阵-不使用选项-无分级
从图3、图4可以看到,他们的区别是使用选项与不使用选项,使用选项,可以看到读取时间很短,8ms就正确读取出来了,而未使用选项时,读取时间达到了1417ms,而且还没有读取出来。
图5 读取数据矩阵-使用选项-不分级
图6 读取数据矩阵-使用选项-分级
图7 读取数据矩阵-不使用选项-分级
从图5、图6可以看到,使用分级与否,对测量结果及测量时间没有影响,仅仅只是会显示出分级的结果,以判断目标质量是否更好。
从图6、图7可以看到,使用选项,对测量结果、测量时间、目标分级都有影响,因此读取条码时,我们优先需要使用选项。下面来看一下此VI的程序框图。
图8 NI 2D Barcode二维条码程序框图
从程序框图中可以看到,其整体的架构是一个While循环,再加一个堆叠顺序结构,再辅助一些其它如条件结构等,构成了整个函数的基本框架。NI的视觉例子,大部分都是以这种类型建立的,这也是为初学者,设置了一个比较容易理解的台阶。
程序框图的作用,如图中注释一样,一开始时有创建缓存、获取NI条码例子文件夹等功能,然后是中间的循环、顺序等,用于读取不同类型的条码,循环执行完后,是释放图像缓存。
顺序的第0帧,是将罗列文件夹函数获得的NI Vision example Image>2D Barcode文件夹下的所有二维条码子文件夹(可以打开此文件夹查看),传入到条码类型列表框的Itemnames属性,并且将值默认设置为0(第一项)。
大家可以看到,在第一帧中,图像引用没有和后面的释放缓存相连,这个东西是可以连可以不连的,因为这是一个引用,在前面已经有其引用号了,后面,如果需要,只需要连接到同样的引用号即可调用相同缓存中的图像进行处理。在高级一些的编程中,一般都是使用While循环加移位寄存器,做成动作器,那样可以复用移位寄存器存储图像缓存,从而在不同的地方调用图像缓存,而且不需要连线,可以大大改善程序框图质量。
图9 NI 2D Barcode二维条码程序框图顺序第1帧
第1帧中主要是完成读取图片。使用的方法是根据条码类型选择的选择,然后将其索引值用于数组索引端,读取文件夹相应的2D条码子文件夹,然后创建文件夹,再罗列新建的文件夹下的所有PNG文件,并且对文件总数计数,与WHILE循环的i比较,不同i值,获得不同的图像,然后通过IMAQ Read读取此文件。这里需要注意,本函数将条码类型复用顺序局部变量传递给了后面的帧中使用。
图10 NI 2D Barcode二维条码程序框图顺序第2帧
第二帧,主要是用于计时开始,没有什么好解释的,一个秒表而已。也使用了顺序局部变量将时间传递给后面的顺序结构,用于计算读取条码时间。
图11 2D Barcode二维条码程序框图顺序第3帧
图12 2D Barcode二维条码程序框图顺序第3帧(假)
第三帧,主要是读取二维条码数据函数,这里分了Data Matrix、PDF417、QR二维条码三类,选择条件由第1帧中的条码类型确定。这里用到的读取条码函数,与前面文章读取LCD中的函数在同一面板下,即函数>视觉与运动>Machine Vision>Instruments Readers,如图13所示:
图13 读取条码函数
接着看一下读取数据矩阵IMAQ Read Matrix Barcode 3函数的接线端,如图14所示:
图14 IMAQ Read Matrix Barcode 3函数
此函数后面有一个数字3,而NI例子中使用的是IMAQ Read Matrix Barcode 2函数,最主要的区别是3比2多了一个Mean Light出线口,用于测量平均亮度。
Data Matrix Search Options:数据矩阵搜索选项,包含了角度方向、阈值、解调模式、单元样本尺寸等。这些参数可以查看帮助文档,查看其中包含的具体内容,也可以查看VBAI相关章节,了解其含义。
Data Matrix Description Options:数据矩阵描述选项。包含了数据矩阵的行、列、比率、条码极性、镜像等。
ROI是兴趣区域,如果不连接,则针对整个图像查找二维条码。
Prepare for Grading? 准备分级,如果要进行分级,则需要先在这个函数中,设置准备分级,0为不准备,1为准备。
Data Matrix Size Options:数据矩阵尺寸选项。包含最小尺寸、最大尺寸、静态区域尺寸等。
Advanced Options高级选项。主要用于一些算法的选择及值设置。
Data Matrix Repot数据矩阵报告,用于输出读取的数据矩阵。主要包含了是否找到、数据、条码边框等数据。可以根据需要选择需要的数据用于输出。
Mean Light平均亮度。
这些参数在NI的例子,使用了一个Get Data Matrix Options函数。这个函数是NI编写的,没有在Vision中,所以大家如果需要使用此函数,可以从本例子中拷贝出来,然后按照例子中的方法,进行连接。当然,也可以直接使用常量或控件,连接到相应的输入端。
图15 IMAQ Grade Data Matrix Barcode函数
IMAQ Grade Data Matrix Barcode分级数据矩阵条码函数,这个函数与例子中看到的IMAQ Grade Data Matrix Barcode AIM函数略不一样。IMAQ Grade Data Matrix Barcode函数是一个多态VI,里面包含了IMAQ Grade Data Matrix Barcode AIM DPM,ISO 16022,ISO 15415三个函数。因为可以根据不同的标准对条码进行分级。这个函数,没有输入接口,只需要在前面的IMAQ Read Matrix Barcode函数中设置Prepare for Grading? 准备分级即可在这里使用目标分级功能。而输出则分为两部分,一部分为AIM Grading Report目标分级报告(其它函数为其相应的函数),另一输出端口为AIM Score Report目标得分报告。一般来讲,使用分级报告就可以。对于条码识别来讲,可能我们只需要得到条码中的数据即可,因此分级函数,通常来讲,是不需要的。
图16 PDF417二维条码读取
图17 PDF417二维条码读取(假)
读取PDF417二维条码相对来讲,就简单了,只有一个IMAQ Read PDF417 Barcode函数,这个函数的说明如图18所示,读取了条码后,是一个简单的判断与数据输出,条码数量需要大于0才OK。
图18 NI IMAQ Read PDF417 Barcode读取PDF417条码
读取PDF417条码比较简单,没有什么参数可以设置,ROI大家都明白,不连接时,整个图像中查找目标。Search Mode搜索模式为搜索多个条码和搜索单个条码。默认是搜索单个条码。Barcodes为条码输出,其中包含的信息如下图19所示:
图19 Barcodes包含的条码信息
Type类型:代码类型
Binary二进制:表明条码是否包含ASCII文本或非ASCII二进制数据
Data数据:函数读取的条码的具体数据
Bounding Box条码边框:可以用于后面的Overlay。
Errors Corrected错误校正:VI使用固有的错误校正方法的校正的错误数
Erasures Corrected清除校正:VI使用固有的错误校正方法的校正的错误数
Rows行:条码中的行数
Columns列:条码中的列数
Number of Barcodes条码数量:输出查找到的条码数量。0为未找到条码。
图20 QR条码读取-使用选项
图21 QR条码读取-不用选项
QR条码读取与数据矩阵类似,也可以使用选项,如果使用选项,或不使用选项,建议使用选项,速度、成功率会提高许多。QR码没有分级。因此其后面的数据输出,与PDF417条码读取一样。大家了解即可。
图22 IMAQ Read QR Code读取QR码
读取OR码函数与读取数据矩阵函数类似。
QR Search Options搜索选项:旋转角度、边缘阈值、解调模式等参数
Image图像:原始图像输入
ROI兴趣区域:在指定的区域中查找QR码,不指定为整幅图像
QR Description Options描述选项:最大尺寸、条码极性、镜像模式、QR模式等
Error in错误输入:通用错误输入
QR Code Cell Size条码单元尺寸:最小、最大尺寸等
Image(duplicate):图像输出
QR Code Report条码报告:输出条码信息数据,含找到否、数据、条码边框等内容
Tokenized Output Data:Tokenized数据输出,包含数据流模式、模式数据、条码数据等。
Error Out:通用错误输出
函数>视觉与运动>Machine Vision>Instruments Readers函数面板中的条码相关的函数,在上面已经讲解了,其中还有一个IMAQ Read Barcode读取一维条码的函数,这个在后面其它的例子中,再讲解。接下来看一下本2D条码读取例子后面的程序。
图23 计算读取条码时间
顺序结构的第4帧为计算第3帧中的条码读取时间。这种方式在许多编程中,都用于计算处理时间,即在处理开始时设置一个时间计数器,然后处理完成后再设置一个时间计数器,后面的-前面的时间计数器,从而得到相应的图像处理时间。
图24 调整图像位置-以条码中心为中心点居中
顺序的第5帧,主要是完成图像位置的调整,其以条码边框的中心点为图像的中心,进行居中。首先获边框的左上、右下两点的坐标,然后相加再除以2得到位置的中心点,再将中心点赋值给Image控件的属性节点Image Center Position图像中心位置,在设置中心位置之前,需要先调用Image控件的方法节点Refresh Image刷新图像。
注意:使用图像中心位置属性,必须图像的显示面积超出Image的框架面积才有实际作用,当使用了Zoo to fit属性,或者是图像在Image控件中已经全部显示完整了,这个属性是不能发挥作用的。因为整个图像都已经可以查看到了,也就不需要对图像进行移动了。这个属性的应用意义在于,当图像很大目标很小时,查看图像放大了N倍时,可以使用此属性进行设置,让目标在Image控件中心显示出来。
图25 顺序结构第6帧-延时
顺序结构的第6帧,主要是用于延时(调用延时函数),这样方便用户观察处理结果和图像,也有模拟实际应用中的时间间隔的作用。
这样这个条码读取函数,就被我们解读完毕。大家可以按照需要,对此函数进行必要的修改后,就可以完成一个条码读取的实际应用函数。如添加图像采集功能、添加生产者消费者模式、添加配置文档、添加智能判断条码功能等。这里就不深入了解了,只能靠各位自己,需要各位先对LabVIEW有比较熟的应用哦。