图像处理、分析与机器视觉
上QQ阅读APP看书,第一时间看更新

4.2 内存图像管理

机器视觉算法多是在计算机的内存中对图像数据施加各种变换,以进行进一步判断。因此在进行各种机器视觉算法开发之前,都需要先在内存中为图像分配足够的空间,再将数字化的图像数据传送至相应的空间,以便进一步分析处理。一旦图像数据进入内存,就可以获知其类型、尺寸和边界以及它包含的用户自定义数据或与机器视觉系统相关的信息。必要时可在内存中复制图像数据,更改图像尺寸和类型,操作图像的边界,读取或移除用户自定义数据与机器视觉系统相关的信息。所有这些为了算法顺利执行而事先分配内存、读写图像属性信息或对图像数据进行复制、替换以及程序结束前释放为图像分配的缓冲区的操作都与内存图像的管理相关。

NI Vision为内存图像管理提供了功能完善的VI集,包括图像内存管理、对内存中的图像进行复制、更改尺寸和类型、处理边界数据以及用户自定义数据与机器视觉系统相关信息等各个方面。这些VI位于LabVIEW的Vision and Motion→Vision Utilities→Image Management函数选板中,如图4-7所示。

图4-7 内存图像管理VI

为了便于理解,表4-2按照类别对这些VI重新进行了归类和汇总。表中第一个VI——IMAQ Multi-Core Options用于设置或获取机器视觉应用可使用的处理器内核,以提升其整体处理能力。IMAQ Create和IMAQ Dispose在第3章已经用过,通常来说它们应相互对应,协同管理图像缓冲区的分配和释放。应注意在使用IMAQ Create为图像分配缓冲时,必须为每个缓冲区指定一个独一无二的名字,并要明确说明其中所存放图像的类型。此外,IMAQ Dispose不仅可以释放某一图像缓冲区,也可以释放它执行之前程序为图像所分配的所有缓冲区,只要设置其All Image参数为True即可。

表4-2 NI Vision图像管理VI

IMAQ Create在为图像分配内存时,还可以指定图像边界的大小。默认情况下图像边界的大小为3像素,也就是说,如果要对图像使用7×7以下大小的算子,则无须对图像边界大小做任何改动。然而某些情况下,如果要使用更大的算子或要根据不同的算法更改图像边界中像素的值,则需要使用IMAQ ImageBorderSize和IMAQ ImageBorderOperation两个VI更改图像边界。

IMAQ ImageBorderSize可读取或更改图像边界的大小,IMAQ ImageBorderOperation则可以填充或更改图像边界中像素的值。如前所述,在填充图像边界中的像素值时,可根据要使用的算法不同在置0法、复制法或镜像法中进行选择。IMAQ ImageBorderOperation默认使用镜像法对边界数据进行填充,若需要使用其他方法,只要设置其Function参数即可。

除了图像边界操作VI、NI Vision还提供了读取和设置图像尺寸、与图像关联的测量单位、两相邻像素代表的水平和垂直距离等信息的VI,这些VI的使用方法均类似。图4-8给出了图像属性操作的例子。一开始程序会弹出对话框让用户选择要打开的文件,此后IMAQ GetFileInfo会获取文件中图像的类型,并传递给IMAQ Create用于为图像读取分配内存。IMAQ ReadFile将打开文件中的图像数据读入分配的内存中后,IMAQ GetImageInfo就可以获知图像的尺寸。IMAQ SetImageSize可以改变图像的尺寸,此处该VI将XY方向上的尺寸各增大了一倍。IMAQ ImageBorderSize和IMAQ ImageBorderOperation将图像的边界尺寸从3更改为4,且按照复制法填充边界像素的值。

图4-8 图像属性操作

在机器视觉系统开发过程中,经常会将机器视觉系统信息与用户自定义数据附加在图像数据上传递,以方便计算。机器视觉系统信息通常包括系统校准信息(Calibration)、灰度或彩色图像的模式匹配模板(Grayscale/Color Template)、无损图层(Overlay)、几何匹配模板(Geometric Template)、黄金匹配模板(Golden Template)等。NI Vision提供了检测图像中是否包含机器视觉系统信息或用户自定义数据的VI,也提供了向图像中添加或从中移除这些信息的VI。图4-9通过图像中用户自定义数据的读写展示了如何使用这些VI。

图4-9 读写用户自定义数据

程序先打开与VI同目录下的motor01.png图像,并将其读入内存。此后程序使用IMAQ Write Custom Data连续向图像数据中添加了两个用户自定义数据MotoNr和MotoPW,这两个用户自定义数据分别用Key1和Key2两个键值进行索引。IMAQ Is Vision Info Present 2用于检测图像数据中是否包含机器视觉系统信息或用户自定义数据(表4-3)。可以预见,在成功地向内存图像添加了用户自定义数据后,IMAQ Is Vision Info Present 2的返回值一定是TRUE。

表4-3 IMAQ Is Vision Info Present 2可检测的信息

IMAQ Get Custom Keys可返回所有用户自定义数据的键值,如果需要所有图像中的用户自定义数据,则可使用循环索引和IMAQ Read Custom Data与之配合逐一读取。此处直接读取了键值Key2对应的用户自定义数据MotoPW,并随后从图像中删除了该用户自定义数据。使用IMAQ Remove Vision Info 2不仅可以删除机器视觉系统信息,还可以删除用户自定义数据(IMAQ Remove Vision Info)。与IMAQ Read Custom Data不同的是,它在删除时并不只是删除某一键值对应的用户自定义数据,而是删除所有图像中的用户自定义数据。

IMAQ Copy可以在算法对内存中的图像数据更改前对其进行整体复制。所谓整体复制是指不仅复制源图像的像素值,还会复制源图像的边界、图像中的机器视觉系统信息以及用户自定义数据等。例如图4-10所示的例子中IMAQ ReadFile将图像数据读入IMAQ Create分配的内存Src中后,IMAQ Write Custom Data会将用户自定义数据与内存图像关联在一起。如果此时IMAQ Copy将源图像Src复制到目标内存Dst中时,则所添加的用户数据也会一并被复制。因此,IMAQ Read Custom Data所读出的目标内存图像中的用户自定义数据可能和之前向源图像中添加的用户数据相同。

图4-10 IMAQ Copy实例

IMAQ ImageToImage 2可以将一幅尺寸较小的图像复制到另一幅比它大的图像中,它常用于使用小图像替换大图像中的某个部分。IMAQ ImageToImage 2的工作原理可通过图4-11进行说明,它以一大一小两幅源图像的引用、目标图像的引用、小图像到大图像原点之间的距离Offset Left/Top以及图像遮罩Image Mask作为输入,用小图像替换其所覆盖的大图像区域。如果使用一幅8位的图像作为图像遮罩参数,则在复制时仅使用小图像中被遮罩图像中非零像素所覆盖像素替换大图中的像素。图像遮罩相对于小图像原点的位置用IMAQ SetOffset设定。如果需要,也可使用IMAQ GetOffset读取遮罩相对于图像原点的信息。使用图像遮罩可以有效减少算法要处理的数据量,有关遮罩的技术细节将在后续章节结合感兴趣区域(Region Of Interests, ROI)的概念进行详细介绍。

图4-11 IMAQ ImageToImage 2工作原理

图4-12给出了一个使用IMAQ ImageToImage 2的实例。程序一开始使用三组IMAQ Create和IMAQ ReadFile分别为大图、小图、遮罩图像在内存中分配了缓冲区,并从图像文件中读入各图像数据到内存中。同时另一个IMAQ Create也为复制后生成的图像在内存中分配了缓冲区。IMAQ SetOffset设置遮罩图像在XY方向上相对于使用它的图像原点的距离。此处设置遮罩图像相对于小图像原点在XY方向上的距离分别为50个像素。这样如果IMAQ ImageToImage 2指定小图像在XY方向上相对大图原点的距离分别为10像素,则最终获得的目标图像就是,小图像中被遮罩中非零像素覆盖的部分替换了大图像中的部分像素。这些替换像素的位置由大小图像原点之间的距离、遮罩相对于小图像的距离以及遮罩中非零像素的位置共同决定。

图4-12 IMAQ ImageToImage 2实例

除了整幅图像的操作,NI Vision还提供了访问部分或某一特定像素的手段。IMAQ GetImagePixelPtr可以获取或释放图像中某一像素的指针以及图像边界、图像行宽度、像素的字节数以及从当前像素指针直到图像结束的可传送字节数(Transfer Max Size)等内存图像的结构信息。为了确保没有任何内存泄漏,IMAQ GetImagePixelPtr获取和释放功能应成对出现,如图4-13中NI Vision自带的例子程序所示。

图4-13中的程序可以将C代码创建的图像复制到NI vision VI在内存中为图像分配的空间中。程序先使用IMAQ Create在内存中为图像分配空间,并设置内存图像边界为3。此后使用IMAQ SetImageSize将内存图像宽度和高度设置为指定的大小。IMAQ GetImagePixelPtr返回内存中图像的指针,并返回图像中每行像素的宽度。注意,此处的行宽不仅包括图像每行的像素数量,还包括图像的边界和左右对齐。CLF结点会调用DLL中的C语言函数Copy_C_Image_To_LabVIEW_Image。这个函数将根据参数创建一个尺寸与之前在内存中所创建的图像一样的临时图像文件,并将所有像素值置为128后复制到之前创建的内存图像中。最后IMAQ GetImagePixelPtr释放之前获取的图像指针,以确保内存安全。

图4-13 IMAQ GetImagePixelPtr实例

程序中Call Library Function结点调用的DLL代码如下。

有关LabVIEW中调用DLL的技术,请参阅本书作者的《LabVIEW虚拟仪器项目开发与管理》一书。

不同的机器视觉系统算法往往基于不同类型的图像进行计算,很多时候需要将前一模块的输出图像转换为后续模块支持的图像类型,才能使算法顺利运行。图像类型转换通常涉及不同位数像素的转换、不同色彩空间像素的转换以及实数域与复数域像素之间的转换等问题。

将位数较少的像素转换至位数较多的像素时,可以采用直接复制法或查找表(Lookup Table, LUT)。直接复制法的依据是位数较少像素的取值范围覆盖位数较多像素的取值范围,采用它不会对图像精度有任何影响。查找表是一组可替换灰度图像灰度级的数据,这些数据由源灰度图像中的像素值进行索引。查找表中数据的个数由源图像的像素位数决定。若源图像为8位灰度图,则查找表中有256个数据;而若为16位图像,则查找表有65535个数据。使用查找表对像素值进行映射时,源像素的值相当于查找表中数据的地址。

将位数较多的像素转换为位数较少的像素时,可以使用移位剪裁法或位深度法。移位剪裁法依据字节高位比低位对数值影响大的特点,一般先将像素字节的各位右移若干位(相当于不断除2),再将超出取值范围的值设置为该范围的最大或最小值,得到各个目标像素的值。位深度法则事先在源图像中约定位数较多的像素转换为位数较少的像素时应使用的位数,随后再对数据进行映射。例如,可规定16位带符号类型的源图像转换时位深度取8~15之间的某个值;16位无符号类型和64位无符号RGB类型的源图像的位深度取8~16之间的某个值。

RGB和HSL颜色空间之间的转换方法在第3章已经介绍过。当位数较多的彩色像素转换为位数较少的彩色像素时,若在同一颜色空间上,则可以使用上述位深度或移位剪裁法对各分量进行转换;否则,要先在同一颜色空间将其映射至位数较低的像素,再将其转换至另一颜色空间。例如,类型为RGB64的图像转换为类型为RGB32的图像时,就可以根据源图像的位深度或移位法将图像转换为32位RGB类型;而若要将其转换为类型是HSL32的图像时,则必须先将其转换为类型是RGB32的图像后,再将其转换为HSL32类型。

不同颜色空间的彩色像素与灰度像素之间的转换方法略有不同。RGB彩色像素转换为灰度像素时,可以用3个颜色分量的平均值来表示灰度像素;而若是HSL彩色像素,则可以直接将亮度分量作为灰度像素的灰度,忽略色调和饱和度信息。反过来,如果要将灰度图像转换为RGB彩色图像,则每个RGB颜色分量均等于源灰度像素的值;而若要将灰度图像转换为HSL彩色图像,则需要将其亮度分量设置为源灰度像素的值,色调和饱和度分量置为0。当然,若转换过程中涉及位数较多的像素向位数较少的像素转换的情况,仍可参照前述情况处理。

为方便在频率域分析处理图像,也可在实数类型与复数类型图像之间进行转换。实数域的像素转换为复数域时,复数域像素的实部代表像素的灰度。也就是说,源图像为灰度图像时,复数的实部等于源像素的灰度值,虚部为0。源图像为彩色RGB图像时,实部为源像素R、G、B 3个分量的平均值,虚部为0。源图像为彩色HSL图像时,实部为源像素的亮度分量,虚部为0。复数域的图像向实数域的转换也可简单分为3种情况。一是向实数域灰度图像转换,这时可设置实数域像素值为源复数像素值的模(实部与虚部平方和的均方根)。另外两种情况与彩色像素相关:一种是向RGB彩色图像转换,这种情况下可设置R、G、B各分量的值均为源复数像素值的模;另一种是向HSL彩色图像转换的情况下,目标像素的亮度分量被设置为源复数像素值的模,色调和饱和度分量被置为0。

IMAQ Cast Image可以将源图像(Image Src)的类型转换为指定的图像类型。表4-4汇总了它可以处理的各种情况以及其在进行图像类型转换时遵循的规则。IMAQ Cast Image封装了进行各种图像转换时的复杂计算,开发人员可以在使用时将注意力集中在VI对图像数据的操作结果上,而无须关心图像转换的具体细节和实现。

表4-4 图像类型转换规则

续表

图4-14显示了IMAQ Cast Image的输入输出参数,以及使用它将32位RGB格式的图像(RGB-U32)转换为HSL图像(HSL-U32)的实例。程序先将彩色图像pepper.png以RGB-U32格式读入内存,随后立即使用IMAQ Cast Image将其转换为由其输入参数Image Type指定的HSL-U32格式。IMAQ Cast Image的参数Image Dst指向转换后的图像引用。右移位数参数#Shift仅在16位图像转换为8位图像的情况下有效,用于说明使用移位剪裁法进行图像类型转换时各16位像素值应右移的位数,其值最大为8。如果#Shift的值为0~8之间的某个值,则IMAQ Cast Image在将16位像素值右移后,会将超出0~255的值剪裁至相应的极值。如果设置#Shift为0,则VI会直接使用位深度法转换图像;若设置其值为-1,VI将忽略位深度并且不对像素值进行任何移位。查找表参数Lookup Table是一个包含256或65536种数据值的数组,它仅在8位、16位或32位浮点数图像类型之间转换时有效。

程序在完成图像格式转换后还进一步使用IMAQ ColorPlaneExaction分别提取了HSL格式图像的3个分量。提取出来的3个分量分别存放在单独分配的8位灰度图像缓冲区H、S、L中。由图中程序的运行结果可以看出,HSL格式图像的L分量包含了图像的所有亮度信息。IMAQ ColorPlaneExaction位于LabVIEW的Vision and Motion→Vision Utilities→Color Utilities函数选板中,它不仅可以提取HSL格式图像的各个独立分量,还能提取RGB、HSV(Hue、Saturation、Value)或HIS(Hue、Saturation、Intensity)格式图像的各个分量。开发人员只需要通过其参数Color Mode切换即可。

图4-14 图像转换实例及运行结果

机器视觉系统通常由多个实现不同功能的处理单元构成。如基于网络分布式结构的机器视觉系统中,图像采集、处理、分析以及运动控制任务可能分别由不同的计算机来完成。这些通过网络通信协同工作的计算机上可能运行不同的操作系统。我们知道,不同的操作系统会按照不同的字节顺序在内存或文件中存放数据,Windows使用从低到高的顺序(Little-Endian,Intel),UNIX等系统则采用由高到低的顺序(Big-Endian,Motorola),因此在不同系统之间传送图像数据时,需要确保字节顺序与操作系统兼容。

NI Vision提供了操作图像数据字节及其顺序的VI,包括IMAQ Flatten Image to String、IMAQ MemPeek及IMAQ CharPtrToString。这些VI可以与LabVIEW的字符串类型转换函数(如Flatten to String和Unflatten String等)配合,轻松实现图像字节顺序的交换等操作。在上述VI中,IMAQ MemPeek可以将void*类型的指针所指位置开始的一定数量的字节复制为字符串输出。IMAQ CharPtrToString复制并转换char*类型指针所指向的C语言字符串(以\0结束)为LabVIEW字符串后输出。这两个VI适合通过CFL处理DLL中代码所处理的图像数据。IMAQ Flatten Image to String不仅可以根据用户配置以字符串形式返回图像的引用、像素数据以及其中包含的机器视觉系统信息,还能指定返回数据的压缩方式,如表4-5所示。

表4-5 图像类型转换规则

LabVIEW的Flatten to String与IMAQ Flatten Image Options组合使用的效果与IMAQ Flatten Image to String的效果相同,但是IMAQ Flatten Image Options更改参数后,所有使用参数的VI均会受到影响。相反,IMAQ Flatten Image to String中所配置的参数仅与其所操作的图像相关。图4-15所示的程序显示了使用这些VI在图像数据与字符串之间进行转换的例子。在把图像文件中的数据读入内存后,程序分别使用IMAQ Flatten Image to String和Flatten to String与IMAQ Flatten Image Options组合的两种方法将图像转换为LabVIEW字符串。两种方法均要求不压缩的情况下以字符串形式返回图像数据和图层信息。对于返回的字符串,程序使用了Unflatten String又将其转换回图像,此处可以根据目标操作系统设定转换时是应用Big-Endian还是Little-Endian字节顺序。

图4-15 图像数据与字符串间的转换

如果将Image控件分别连接到使用两种转换方法得到的图像引用上,可以发现这两种方法的效果完全相同。此外,程序中Unflatten String再次将字符串转换回图像时,使用了Big-Endian方式,若选择其他字节顺序,可以发现转换后的图像与源图像不同。由此可推断LabVIEW采用Big-Endian方式来组织数据字节。

图4-15所示的程序实际上暗示了在网络中传送图像时处理字节顺序的方法。考虑从网络中一台安装有LabVIEW的Windows终端分别向另外两台UNIX和Windows终端传送图像的情况,如图4-16所示。由于LabVIEW按照Big-Endian的方式处理字节顺序,因此发送端要先把从Windows系统中读取的图像数转换为Big-Endian,才能在LabVIEW中处理并广播至网络。接收端在收到按照Big-Endian编排的数据后,必须按照操作系统和终端上所安装的应用支持的字节顺序重新安排字节,才能使图像处理正常进行。例如在保存图像时,接收端1上的应用要按Big-Endian方式将字节写入图像文件,接收端2上的应用则采用Little-Endian方式。

图4-16 图像数据与字符串之间的转换

基于网络的分布式机器视觉系统中,可以将NI Vision和LabVIEW Real-Time Module结合,实现远程显示(Remote Display)和RT Video Out两种图像显示方式。Remote Display方式用于开发调试过程中通过本地工作站查看远程终端上采集或处理的图像。如果远程终端上可以外接显示器,则可以使用RT Video Out方式将图像显示在连接到终端的显示器上。

挡在LabVIEW程序中使用图像显示控件或任何诸如IMAQ WindDraw、IMAQ WindToolsShow或IMAQ ConstructROI等NI Vision提供的图像外部显示VI时,远程显示方式将会自动被激活。使用远程显示方式时,大量的图像数据必须经过网络传输至本地工作站,这通常不仅要占用较大的网络带宽,还会降低显示系统的实时性。IMAQ Remote Display Options可以设置远程显示模式下,对用于显示的图像数据副本(注意,并不压缩原始图像数据)进行压缩,以减少网络带宽的占用。支持的压缩方式与IMAQ Flatten Image Options的可选压缩方式相同,即JPEG有损压缩方式和无损的二值图像打包方式。其实在LabVIEW 8.0之前的版本中,如果要对远程显示方式下图像的压缩方式进行设置,必须使用IMAQ Flatten Image Options。由于使用IMAQ Flatten Image Options会导致图像转换为字符串及远程显示相互影响,因此在LabVIEW 8.0及其之后的版本中,使用IMAQ Remote Display Options和IMAQ Flatten Image Options将配置工作进行了隔离。

应注意,远程显示方式会随着系统连接的状态被激活或禁用,而且它也是VI前面板的特性之一。也就是说它的运行必须依赖正常的系统连接和VI前面板的存在。此外,由于传输的数据量较大,远程显示方式会占用较大的网络带宽,因此对于实时性要求较高的系统应当慎用。通常来说,远程显示模式仅用于开发调试阶段,最终部署的系统应尽可能采用RT Video Out方式将图像直接显示在连接到远程实时终端上。

NI Vision的图像显示VI——IMAQ WindDraw和IMAQ WindClose可直接支持RT Video Out显示方式(只需将参数Window Number control设置为15)。若控制器的BIOS包含VESA Bios Extensions 2.0或更高版本,也可以直接使用IMAQ RT Video Out显示图像到显示器。当然也可以通过IMAQ Video Out Display Mode和IMAQ Image Bit Depth等管理图像显示的VI控制显示区域、图像显示的位深度及刷新率等。有关图像显示的技术在4.3节进行详细介绍。