5.1 图像文件读写
无论是刚采集到的图像数据,还是经过机器视觉算法处理后得到的图像数据,都可以通过不同的方式组织,再以文件的形式保存至各种存储介质,如硬盘、U盘或服务器等。保存图像的文件通常由文件头和紧随其后的图像数据构成。文件头包含了文件中像素数据组织方式的信息,如图像的水平和垂直像素分辨率、调色板等信息。而图像数据则包含了图像各个像素点的灰度或色彩信息等。多数情况下,图像数据都会以某种特定的方式组织存放,以节省存储空间或提高数据访问效率。不同格式的图像文件所使用的数据组织方式各不相同,图像文件的特性也因此各异。
LabVIEW自身集成了对PNG、JPEG和BMP图像文件的支持,这意味着在没有安装NI Vision的情况下也可以使用LabVIEW自带的VI对这3种格式的图像文件直接进行读写操作。这些函数位于LabVIEW的Graphics & Sound→Graphics Formats函数选板中,如图5-1所示。
图5-1 LabVIEW自带的图像文件读写函数
LabVIEW自带的这几个图像文件读写函数可以将图像文件中的数据读入内存,并用簇来组织这些数据。图5-2显示了使用LabVIEW自带的图像文件读写函数的实例。程序先用Read JPEG File.vi将数据读入内存,并用Image Data簇进行组织,其中图像数据被保存在一位数组中。用簇组织的图像数据被称为扁平数据(Flattened Data)。使用LabVIEW的Draw Flattened Pixmap.vi可以直接将扁平图像数据绘制到图片控件中进行显示(注意,图片控件并不能自动按图像尺寸进行显示)。也可以使用Unflatten Pixmap.vi将扁平图像数据转换为用二维矩阵表示的非扁平(Unflatten)图像数据,前提是要事先知道图像数据的编码方式(24位、8位、4位或二值)。LabVIEW为非扁平图像数据的显示也提供了Draw Unflattened Pixmap.vi。
图5-2 LabVIEW自带的图像文件读写函数实例
程序将图像读入内存后,一方面使用Draw Flattened Pixmap.vi进行显示,另一方面用Unflatten Pixmap.vi将扁平的数据转换为非扁平的二维图像数据。紧接着,程序从扁平数据中提取一维像素数组,并将其顺序进行反转,经过重新更新内存中的图像数据并用Draw Flattened Pixmap.vi显示后,就会得到一幅对源图像沿水平方向进行反转的图像。Convolution.vi可以对非扁平的二维矩阵图像数据进行卷积操作,若使用图中所示的尺寸为3×3的卷积核对其处理,并用Draw Unflattened Pixmap.vi绘制处理结果,可以发现该卷积操作可提取图像中垂直的边缘。程序最后使用Flatten Pixmal.vi将卷积计算结果转换为扁平数据,并用Write PNG File.vi将其保存为PNG格式的文件。
上述例子给出了没有安装NI Vision时使用LabVIEW自带函数进行图像读写和处理的例子。使用这种方法时,图像数据被读入到数组中后才进行处理。由于数组在内存的栈区进行分配,而图像处理过程一般都要处理大量数据,因此使用LabVIEW自带的文件读写函数只能进行较简单的图像处理。对于机器视觉应用开发来说,通常需要进行大量的图像数据运算,这就需要使用NI Vision提供的文件读写和处理函数在内存的堆区进行各种操作。
NI Vision不仅可以支持常见的BMP、TIFF、PNG、JPEG、JPEG 2000等标准图像文件格式读写,还支持可存放连续多帧图像的AVI视频文件格式,并且可保存浮点数、复数或HSL类型图像的NI专用AIPD图像文件格式。在通用文件格式中,PNG文件具有保存机器视觉系统空间校准信息、模板匹配信息、图层以及其他用户自定义信息的能力。JPEG和JPEG 2000具有较高的数据压缩率、而AVI文件可以在单独文件保存多帧图像。
不同格式的图像文件组织图像数据的方式和保存的图像类型各不相同。而不同类型的图像在像素位深度、色彩等方面的特点也千差万别。例如BMP文件只能保存8位灰度或32位RGB类型的图像,而PNG文件中则可以保存8位、16位有符号、16位无符号的灰度图像或32位和64位RGB类型的图像。AVI文件可以将多个图像帧和语音同步交错组合在一起存储。AIPD文件则支持任何类型的图像。表5-1显示了NI Vision支持的图像文件格式与图像类型之间的关系。
表5-1 NI Vision支持的常见图像文件格式与图像类型的关系
图像经数字化后生成的数据量较大,因此在存储图像文件时通常都会对图像数据进行压缩,以最大限度地减少存储或传输所需的空间和带宽。根据压缩时是否损失信息,图像数据的压缩方式可分为无损压缩(lossless compression)和有损压缩(lossy compression)。
无损压缩方式通常会对图像数据进行扫描,并在不损失图像信息的前提下,按照某种更有效的方法重新组织并存储图像数据。经重新组织后的数据文件尺寸会明显减小。例如,使用无损压缩方式存储的图像文件可以将图像中重复的图案转换为一个样本和多个索引,或者根据像素强度的变化规律来存储图像数据,以缩小图像文件的尺寸。按照这种压缩方式存放的图像文件经解码后仍可以恢复所有原图像中的信息。
有损压缩算法通过丢弃不必要的信息,仅保留关键的有用信息来减小文件的大小。在可接受的范围内,使用有损压缩可以有效地提高系统的处理能力和响应速度。例如,可以将图5-3所示的条形码图像尺寸缩小到仍足以分辨的程度保存,以减少机器视觉系统处理的数据量。再比如,若要提取图5-4中待测元件的边沿,可以先对图像进行二值化,去除不必要的色彩、灰度等冗余信息,仅保留必要的物体形状,以提高边沿提取的速度。
图5-3 对条形码图像进行有损压缩
图5-4 通过二值化方法去除不必要的信息
AIPD文件是NI专门为机器视觉系统开发而设计的文件格式,它支持包括32位浮点数类型、32位HSL类型以及64位复数类型在内的所有图像类型,其文件后缀名为“.apd”。AIPD文件中的数据紧随在文件标识AIPD之后,不对数据进行任何压缩。NI目前仍尚未公开AIPD文件的格式,但可以通过LabVIEW等NI的软件进行操作,并可将其转换为BMP、TIFF、JPEG/JPEG 2000、PNG等其他标准的图像格式。
使用传统文本语言进行机器视觉和图像处理分析系统开发时,工程人员往往要花费大量的时间和精力研究各种图像文件的结构并编写代码,这种不必要的重复劳动不仅增加了软件开发的成本,还降低了整个系统的稳定性并加长了项目周期。NI Vision针对这一情况,对图像文件的读写等操作进行了封装和测试,提供了一套丰富的图像文件操作VI。使用这些VI,开发者无须关心文件格式等细节,而能够专注于机器视觉应用本身的开发。
NI Vision提供的图像文件操作VI包括图像文件信息获取VI、图像和视觉系统信息获取VI、图像文件读写VI以及AVI文件操作VI等。这些VI位于LabVIEW的Vision and Motion→Vision Utilities→Files函数选板中,如图5-5所示。在LabVIEW中调用这些VI不仅可以快速读写BMP、TIFF、JPEG/JPEG 2000、PNG、AIPD等标准图像文件,还可以读取结构已知的非标准图像文件。当然也可以只获取文件中包含的与图像和机器视觉系统相关的信息,或使图像在不同的文件格式之间进行转换。
图5-6显示了在LabVIEW使用NI Vision读写BMP图像文件的程序代码,其他格式图像文件的读写方法与之类似。一开始,IMAQ Load Image Dialog会显示文件选择对话框,提示操作人员选择要打开的图像文件。该VI与LabvIEW的标准对话框VI相似,但提供了对所选图像文件的预览功能。
图5-5 NI Vision的图像文件操作函数
图5-6 图像文件读写
IMAQ GetFileInfo可以获取所选图像文件的信息,包括图像文件的类型、文件中所保存图像的类型(Image Type)、图像的分辨率(XY Resolution)以及文件数据类型(File Data Type)等参数。文件类型代表图像数据以何种格式的图像文件存放。如果文件为标准图像文件,则返回BMP、TIFF、JPEG、JPEG 2000、PNG或AIPD等标识字符串;若为非标文件,则返回xxx字符串。图像数据类型(File Data Type)代表了文件中所保存图像的位深度、颜色空间、数据的组织方式等信息,其返回值如表5-2所示。
表5-2 图像类型的值
File Data Type的返回值是图像文件头中声明的像素数据类型,如8位灰度图像的返回值为3。图5-7显示了IMAQ GetFileInfo的输入输出参数及其返回的文件数据类型。其中文件数据类型的返回值从0开始顺序递增。例如,返回值等于5时,代表文件中图像的像素使用16位无符号类型。
图5-7 IMAQ GetFileInfo及其返回的文件数据类型
IMAQ Create根据图像的类型等信息为要读取的文件在内存的堆中分配空间。当调用该函数时,NI Vision会在内存堆上先创建一个保存图像名和边界等属性信息的数据结构,但并不立刻为像素数据分配空间。只有等到图像尺寸改变时,才会自动根据实际情况为像素数据分配所需要的空间。图像尺寸改变通常在图像文件读取、图像采集开始或图像被重新采样时发生。IMAQ Create在内存的堆区域为图像分配空间后,就可以返回指向该区域的引用。使用这一引用,就可以访问堆上的图像数据。如果图像处理代码会改变堆上的图像数据,一般需要重新在堆上重新分配空间,复制图像数据。
一旦为要读取的图像分配了足够的空间,IMAQ ReadFile就可以将所选图像文件中包含的图像数据读入内存进行各种处理。IMAQ ReadFile不仅可以将BMP、TIFF、JPEG/JPEG 2000、PNG及AIPD等标准图像文件中的数据读入内存,也可以将结构已知的非标准图像文件数据读入内存。而数据在内存中以何种类型存放取决于其输入参数Image引用所传递的图像类型。也就是说,无论所读取的图像文件为何种格式以及其中包含的图像为何种类型,IMAQ ReadFile函数都会将其自动转换为Image引用所传递的图像类型。
例如,若在图5-8显示的代码中将IMAQ Create的输入参数Image Type人为指定为7=Grayscale(U16),则无论所选择的图像文件包含何种类型的图像,IMAQ ReadFile都先将解码后的数据自动转换为16位无符号的灰度图像,再输入到内存中。利用这一特点,开发人员始终可以直接从图像文件中得到算法需要的图像类型。当然,如果需要在内存中实现不同图像类型之间的转换,则可以使用IMAQ Cast Image。
如果要使用IMAQ ReadFile读取结构已知的非标准图像文件,则需要事先通过File Options输入参数告诉该VI如何读取文件中的图像数据,包括要读取文件中数据的类型,文件中实际图像数据相对于文件头的偏移字节数,是否使用用户自定义的最大最小值对越界数据进行处理,以及8位以上的像素数据采用由低到高(Little Endian, Intel)还是由高到低的字节顺序(Big Endian, Motorola)存放等信息。图5-9显示了IMAQ ReadFile及其File Options参数的结构。关于各参数的详细意义及用法,读者可参考NI Vision的帮助文件。
图5-8 将文件中的图像读取为16位无符号灰度图像
图5-9 IMAQ ReadFile及其File Options参数的结构
在内存完成对图像数据的分析处理后,就可以使用IMAQ Write File 2把处理后的图像及额外的与机器视觉系统相关的信息(如图层、模式匹配模板、系统校准以及文字说明等)保存到图像文件中。目前该VI共有6种实例可供选择,分别用于将数据保存为BMP、TIFF、JPEG、JPEG 2000、PNG图像文件或在PNG文件中保存机器视觉系统信息的情况。使用这些实例,开发人员就可以在各种图像文件格式之间自由转换。需要注意的是,图像文件格式的转换可能导致图像信息损失。例如,将采用无损压缩方式的PNG文件转换为采用有损压缩方式的JPEG文件时,部分图像的细节信息可能会被丢弃。
最后,将处理结果保存到文件并退出程序之前,必须释放在堆上为图像读取所分配的内存。另外,图5-6所示的程序使用了放置在Sequence中的ImageOut控件自动显示图像数据。由于LabVIEW以数据流驱动的方式运行,连接到Sequence上的错误警告簇可以有效避免图像在控件中还未完全显示时内存空间就已经被释放的情况。此外,还需要将图像显示控件的属性设置为Snapshot,以确保释放内存中的数据后,控件中仍可显示之前的图像。
在进行机器视觉系统开发时,可针对不同应用场合,根据各种图像文件格式的特点择优选用。鉴于NI Vision支持的文件类型中BMP、TIFF、JPEG/JPEG 2000、PNG等标准文件在机器视觉系统中的通用性以及可保存多帧图像的AVI文件格式的特殊性,以下几节将对这些图像文件格式逐一进行简要介绍。