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

4.3 图像显示

无论对于正在开发的机器视觉系统还是已经安装部署至现场的机器视觉系统来说,显示机器视觉系统所处理的图像都极为重要。通过图像显示,机器视觉系统能以可视化的方式向开发人员或最终用户展示所处理的数据。当然,机器视觉系统并不一定要显示所有内存中的图像,而只是将必要的临时数据或最终计算结果展现出来。

以LabVIEW和NI Vision作为机器视觉系统开发平台时,可以实现图像显示控件(仅用于LabVIEW 7.0及之后版本)、外部窗口以及ActiveX或.NET控件(CWIMAQViewer)等图像显示方式。图像显示控件可以像其他LabVIEW控件一样被放置在VI的前面板中显示图像。外部窗口则使用一个或多个窗口显示图像,NI Vision可同时处理16个独立的图像显示窗口。NI Vision也可以实现类似图像浏览器的显示方式,同时显示某一目录下的所有图像。图4-17展示了3种NI Vision图像显示方式的效果。

图4-17 NI Vision的图像显示方式

虽然ActiveX和.NET也可用于在LabVIEW中显示图像,但由于图像显示控件和外部窗口法的方便性,几乎无人在LabVIEW中使用这种方式显示图像。然而在诸如Visual C++或Visual Basic等文本语言编程环境中使用NI Vision时,则使用ActiveX和.NET控件显示图像的方法相对更为常见。

图像显示应解决的问题不仅包括如何在显示设备上以最佳效果投射图像数据,还包括设置显示设备的属性(如显示模式、位深度和刷新频率等)以便发挥其最佳性能。此外,调色板(Palette)技术、感兴趣区域(ROI)和不损坏图像数据的图层显示技术等也是与图像显示相关的研究课题。

4.3.1 图像显示控件

图像显示控件是LabVIEW中最直接的图像显示和交互工具,它和其他LabVIEW控件一样,既可作为显示控件,也可作为输入控件。通过VI前面板右键菜单,可从Vision控件选板中选择不同风格的图像显示控件。在图像显示控件中显示图像非常直接,只要将包含图像数据的引用连接到控件的结点即可,如图4-18所示。

图4-18 使用图像显示控件显示图像

图像显示控件有很多属性和方法,通过配置或调用这些属性和方法,可以更改控件的表现和行为。控件属性既可在设计时通过右键菜单选项配置,也可在运行时通过控件的属性结点(Property Node)进行更改。图像显示控件方法的调用和其他LabVIEW控件方法的调用相同,都可以通过方法调用结点(Invoke Node)来实现。例如可以通过右键菜单或属性结点设置图像显示控件的工作模式为快照模式(Snapshot Mode),使控件都能及时显示图像数据的一个副本。如果不使用该选项,则当图像销毁时控件中显示的图像将消失。由于每次都会复制图像数据,因此使用快照模式时程序的运行速度可能会受到影响。若需要在图像显示控件中快速显示图像,则必须禁用快照模式,同时使用Invoke结点调用Refresh Image方法使控件立即更新图像显示。

16位数据到8位数据映射是图像显示控件另一个比较重要的属性,它与显示设备的显示模式(Display Mode)有关。显示设备的显示模式可通过分辨率、显示位深度和刷新频率等参数来说明。其中分辨率设定显示设备显示的区域,刷新频率设定连续多幅图像之间刷新的快慢程度,显示位深度则用于约定显示设备表示颜色的数据位数。目前计算机显卡和显示器配合,通常都可支持1024×768像素显示区域、32位真彩色及60Hz刷新频率的显示模式。彩色显示设备的显示位深度取值在8~32位之间,它决定了显示设备展示颜色的能力。当位深度为8位时,显示设备可以256种颜色显示图像;为16位时,则能以65536种颜色显示;而如果位深度为32位,且数据以RGB方式编码时(每个颜色分量由一个字节表示,第4个字节为Alpha通道),3个颜色分量经过组合可以表示1677万种以上的颜色,也就是我们常说的真彩色。目前大多数彩色显示器都具备32位真彩色显示模式。然而,在工业环境下,仍有某些显示设备只能以8位或16位的位深度显示图像。若图像的位深度大于这些显示设备的位深度,就要考虑如何能以最佳方式显示图像。

在真彩色显示模式下,要显示部分NI Vision支持的图像,也要涉及类似问题。NI Vision支持8位和16位的黑白灰度图像、32位和64位的RGB图像、浮点数和复数类型的图像以及32位HSL类型的图像。在显示设备的位深度大于或等于要显示的图像位深度时,图像的显示相对比较直接。例如,在32位真彩色显示器上可直接显示32位RGB图像和8位灰度图像(RGB各分量均等于灰度值),而无须担心损失任何颜色信息。然而,如果情况刚好相反,则要考虑位深度由高到低的映射。例如若要在32位彩色显示器上显示16位的灰度图像或64位RGB图像,则必须考虑16位像素到各个8位RGB颜色分量之间的映射关系。当然,如果显示设备的性能参数已经明确,也可以先利用IMAQ Cast Image将图像转换为与其位深度相同的RGB图像再进行显示。然而这种使用软件转换类型的方式比直接使用显示器硬件进行映射效率要低,而且从模块化开发的角度来看,这样做会降低显示模块的内聚性。此外,由于大多数显示设备是以RGB方式工作的,一般都先将HSL类型的图像转换为RGB类型后才进行显示,如图4-19所示。

图4-19 图像显示时的类型转换和像素映射

NI Vision支持多种16位到8位数据的映射方法,包括全动态范围映射(Full Dynamic)、既定范围映射(Given Range)、90%动态范围映射(90%Dynamic)、既定比例范围映射(Given Percent Range)以及右移位映射(Downshift)等方法,如表4-6所示。这些映射方法各有优缺点,设计时可根据使用场合择优而用。

表4-6 NI Vision图像显示16位到8位数据的映射

在LabVIEW中可以使用IMAQ Image Bit Depth读取或设置16位灰度图像和64位RGB图像显示时要使用的位深度。所设置的位深度决定了图像中16位数据以何种方式显示、进行类型转换以及以何种方式保存至PNG文件。对于16位有符号图像(I16),位深度的取值范围为8~15;而对于16位无符号和64位RGB图像,其取值范围为8~16。位深度取值为0时,则表示NI Vision将使用图像数据类型的整个动态范围。若图像为彩色RGB图像,则这些设置适用于各个颜色分量。显示设备的参数可以手动在显示设备上进行设置,也可以通过调用操作系统的API通过编程来实现。例如,既可以手动设置计算机显示器的分辨率、刷新率及颜色显示的位深度,也可以调用Windows API更改这些设置。

一旦设定了图像和显示设备的位深度,就可以配置16位数据到8位数据的映射方式。图4-20显示了设计时在LabVIEW中配置图像显示控件的16位到8位数据映射方式为Full Dynamic和Downshift时的情况。图像显示控件数据映射方式的选项列表中有一项为Most Significant Bits,它实际上是Downshift方式右移尾数为8位时的特殊情况。此外,还要注意某些映射方式仅适用于图像显示位深度被配置为0时的情况。

图4-20 图像显示时的类型转换和像素映射

在真彩色显示模式下显示灰度图像时,最常见的处理方法是使RBG各颜色分量均等于灰度图像的像素值,这样就可以像32位RGB彩色图像一样,使像素值与真彩色颜色值一致。与之类似,若能用8位或16数据去索引一系列RGB颜色值组成的数据表,就可以用8位或16位数据来表示彩色图像。这种情况下,RGB颜色组成的数据表称为调色板,使用调色板的图像则称为调色板图像。调色板图像中的像素值并不是真实颜色值,而是颜色值在调色板中的“地址”。调色板可以看作一种特殊形式的查找表,相对于一般查找表来说,表中每项包含的不是一个数据,而是R、G、B 3个颜色分量,因此又称为颜色查找表。

在LabVIEW中显示带有调色板的8位或16位彩色图像时,需要注意图像类型的选择。例如,若图像文件中保存的图像为带调色板的8位彩色图像,则图4-21所示的代码中,IMAQ GetFileInfo识别到的图像类型为8位灰度图。如果IMAQ Create直接使用同样的图像类型在内存中为图像创建空间,则IMAQ ReadFile读取图像数据时只读取8位的像素数据,而忽略调色板,因而显示的图像也为灰度图像。如果要显示出彩色图像,必须在IMAQ Create为图像分配缓存时指定图像类型为32位的RGB图像,这样IMAQ ReadFile在读取图像数据时会利用图像文件中的调色板数据创建各RGB分量,显示出彩色图像。

可以将彩色调色板图像的思想延伸到图像显示方面,在不改变灰度图像数据的前提下,为灰度图像关联或更换调色板,以产生不同的显示效果。例如,可以通过为灰度图像关联调色板,创建类似图4-22中的负光电显示效果(Photonegative Displays)或颜色编码方式(Color-coded Displays)的卫星云图显示效果。这些不同的显示方式有助于突出显示图像中的细节,方便识别灰度图像中难以被精确识别的信息。例如,人眼在较亮环境下对灰度的微小变化要比在较暗环境下敏感,可以通过为灰度图像关联调色板,使较暗环境下灰度的微小变化更清晰地显示出来。

图4-21 读取带调色板的彩色图像

图4-22 负光电和颜色编码方式显示

使用NI Vision可以为8位灰度图像的显示关联调色板(也仅支持为8位灰度图像显示关联调色板)以突出显示图像的细节。例如图4-23,可通过图像显示控件的右键菜单,为灰度图像显示选择预定义的Gradient(梯度)调色板。

图4-23 为图像显示选择调色板

NI Vision为8位灰度图像的显示预定义了5种显示用调色板,如表4-7所示。这些预定义的调色板强调不同灰度区域的显示,开发人员可根据图像中需要重点显示的信息选择合适的调色板。如果预定义的调色板仍不能满足显示的需要,开发人员还可以自行定义用于显示的调色板。

表4-7 NI Vision为灰度图像显示预定义的调色板

图像显示控件自带可在图像中绘制感兴趣区域(ROI)的工具条,其中包括可绘制各种形状ROI的工具,如表4-8所示。用户可以使用这些工具与机器视觉系统交互,指明所处理图像中应重点关注的某个或多个区域。使用ROI可以缩小所处理图像的范围,提高系统的处理速度,增强实时性。在图像显示控件中绘制ROI,可通过选择适当的工具按钮,并按下及拖动鼠标来完成。若要在同一图像中创建多个ROI,可在完成一个ROI绘制后,按住Ctrl键继续绘制下一个。一幅图像中最多可绘制的ROI个数可通过Maximum Contour Count属性来设置。

表4-8 图像显示控件的ROI工具

从原则上来说,所有在设计时可通过右键菜单配置的图像显示控件属性都能在运行时用其属性结点实现同样的配置。不仅如此,还可以使用调用结点(Invoke)在程序代码中调用各种图像显示控件的各种方法函数(Method)。例如,图4-24显示的程序代码就可以使用属性结点设置图像的显示调色板为Gradient(梯度)调色板。其中属性结点所实现的功能与图4-23中使用右键菜单实现的功能相同。程序还使用Invoke结点调用了Refresh Image方法对图像显示控件中的图像显示进行了刷新。实际开发过程中可选择配置或调用的属性和方法很多,但无论哪种属性或方法,其配置或调用的原理都类似。

图像显示控件是LabVIEW和NI Vision结合开发机器视觉系统时最为常用的图像显示工具之一,它可与其他LabVIEW控件共同嵌入VI的前面板中。如果要创建集式中图像显示与交互界面,它是较为理想的选择。

图4-24 使用属性结点配置图像显示控件

4.3.2 图像浏览器

Windows资源管理器以缩略图方式查看文件的方式非常适合浏览文件夹中的多幅图像。在LabVIEW中使用NI Vision函数也可以创建以缩略图方式查看图像文件的图像浏览器。这些函数位于LabVIEW的Vision and Motion→Vision Utilities→Image Manipulation→Browser函数选板中,如图4-25所示。

图4-25 Browser函数选板

NI Vision提供了一种基于图像显示控件创建图像浏览器的方案。其基本思想是:先对要显示的多个图像进行重新采样生成缩略图,再将这缩略图按照预先设定的方式组织成一幅图像,并在图像显示控件中显示。根据所浏览的文件夹中图像文件的增减或变更情况,图像显示控件中的缩略图也可进行添加、删除以及替换等操作。由于各个缩略图代表了不同图像,显示时可以为它们添加边框进行区别。当用户选择某个图像时,可通过更改边框的颜色显示选择焦点。开发人员可以在程序中捕捉诸如鼠标单击、双击等事件,并在事件处理器中定义程序应对这些操作做出何种响应。

NI Vision基于这种思想创建图像浏览器的VI如表4-9所示。IMAQ Browser Setup可以设定图像浏览器如何显示缩略图,包括它的大小、背景、浏览器中每行显示缩略图的数量、每幅缩略图的长宽显示比例(通常NTSC制式下采集的比例为4:3,PAL制式下采集的图像为3:2),以及每幅缩略图边框的风格和大小等。它需要事先在内存中分配一个图像缓冲区作为输入,运行后该缓冲区的类型会被调整为代表图像浏览器的类型,其引用会作为输出参数供其他图像浏览器VI使用。由于图像浏览器基于图像显示控件来创建,因此本质上IMAQ Browser Setup所输出的图像浏览器引用仍为图像引用。

表4-9 创建图像浏览器的VI

IMAQ Browser Insert/Replace/Delete用于维护浏览器中显示的图像。使用这些VI可以在其中添加、删除或替换图像的缩略图。IMAQ Browser Insert会对原图像在水平、垂直方向重新采样生成缩略图,并将其添加到图像浏览器的首个空闲位置(at first free)或末尾(at the end)。如果末行所有空闲位置均被占用,则会重新在浏览器中添加一行。为确保生成的缩略图与原图尽可能有相同比例,VI对原图像重采样时,两个方向将采用相同的采样率。IMAQ Browser Replace可用一幅新的图像替换图像浏览器中指定位置的已有缩略图。在完成缩略图替换之前,该VI也会对新图像进行重新采样生成新的缩略图。IMAQ Browser Delete用于删除浏览器中的某个缩略图。开发人员可以通过Reorganization Mode参数选择删除后是要保持被删除缩略图的位置为空闲,还是要占用该位置并重新排列所有缩略图。如果VI需要指定缩略图的位置,则可通过缩略图索引(index)、缩略图在浏览器中的行列号(又称为矩阵索引,matrix index)或缩略图中任意像素的位置(pixel position)来说明。

IMAQ Browser Focus Setup和IMAQ Browser Focus用来处理图像浏览器中的焦点。当程序捕获到用户选择某个图像的事件时(鼠标点击缩略图),可以用IMAQ Browser Focus设置图像的状态为“选定”或“取消选定”。从显示效果来看,被选定的图像将被设置“焦点”,且具有焦点的缩略图边框颜色将被置为IMAQ Browser Focus Setup预先设定的色彩。如果要判断当前图像浏览器中某个图像是否已被选择,可将IMAQ Browser Focus的Get/Set参数切换到Get,并根据其返回的State Out值来判断。

图4-26给出了一个图像浏览器示例的程序代码及运行界面。程序一开始先对需要的图像浏览器进行配置。IMAQ Browser Setup配置需要的图像浏览器特征如下:长宽为400×300像素、灰色背景、每行显示三幅缩略图、3个像素宽的突起风格边框以及缩略图像素比为4:3。IMAQ Browser Focus Setup将焦点图像缩略图的边框显示颜色设置为绿色。从IMAQ Browser Setup得到其输出的浏览器图像引用“Image Browser Ref”后,For循环中的IMAQ ReadFile和IMAQ Browser Insert将逐个读入指定文件夹中的bmp和png文件,并将它们添加到所配置的图像浏览器中。应注意此处为了读取图像文件需要额外在内存中分配缓冲,图像读取完成后即可立即释放。

程序中的While循环充当事件处理器的角色,它捕捉并处理图像浏览器中的鼠标单击事件。若用户在图像浏览器中单击鼠标,分支结构中的IMAQ Browser Focus先按照鼠标所点击的位置,获取相应缩略图的当前选择状态,再将所点击缩略图的选择状态设置为其当前选择状态的相反值。为了不让图像浏览器中ROI干扰“焦点”图像的显示,程序使用了Image图像显示控件的“Clear ROI”方法清除所有ROI。每次循环执行的最后,更新完成的图像浏览器图像都会在图像显示控件被重新绘制。当用户点击Stop按钮退出程序时,IMAQ Dispose将释放为图像浏览器图像显示所分配的缓冲区。

图4-26中的代码提供了一个图像浏览器的简单原型,可在其基础上修改While循环中的事件处理代码,进一步添加更多功能。例如,可以使代码捕获鼠标双击事件,在相应的事件处理分支中添加显示所双击图像的代码;也可以添加代码,使用户在图像浏览器中能直接删除图像文件。

图4-26 图像浏览器示例

图像显示控件和图像浏览器配合可以满足大多数集中交互式界面应用程序图像显示的需求,但是在某些情况下,用户仍希望能在一个或多个独立的窗口中显示图像,这就要用到NI Vision的外部窗口图像显示方法。

4.3.3 外部窗口显示

使用外部窗口与图像显示控件显示图像的基本原理类似,不同之处在于前者在独立于应用程序主界面的窗口中显示图像,而且主程序的代码可以配置窗口外观,控制窗口属性以及窗口附带ROI工具条的使用。外部是相对于程序主界面而言的,意味着窗口不像图像显示控件那样是主界面的一部分,而是相对于程序主界面独立。图4-27显示了NI Vision用于支持外部窗口图像显示的各种VI,它们位于LabVIEW的Vision and Motion函数选板中,选择路径为Vision and Motion→Vision Utilities→External Display。

图4-27 NI Vision外部窗口图像显示VI

使用程序代码在外部窗口中显示图像的总体思路是:配置窗口属性→显示外部窗口和图像→控制窗口属性及其工具→关闭窗口。配置窗口属性是指在将窗口展示给用户前,对将要显示窗口的外观进行配置,包括窗口是否包含滚动条、状态条、标题栏以及窗口是否可被缩放等。一旦确定了窗口的外观,就可以将其连同要显示的图像一并绘制在屏幕上。NI Vision可支持16个外部窗口同时显示,各个独立的外部窗口通过在0~15之间取值的窗口编号(Window Number)来识别。程序不仅可控制窗口缩放、移动、隐藏或再次显示,还能控制窗口的ROI工具条或访问窗口图像中的ROI实现与系统的交互。任务完成后,图像窗口被关闭,控制权就可交还给操作系统。表4-10对一些基本的NI Vision外部窗口显示VI功能进行了说明。

表4-10 NI Vision外部窗口显示VI说明

NI Vision外部窗口显示VI的使用较为简单直接,而且大多数VI的使用方法有类似之处。例如,不少VI兼具属性设置和属性当前值读取的功能,具体使用何种功能,通过VI的读取/设置(Get/Set)参数值进行选择。图4-28所示的代码中,第一个IMAQ WindSize先获取窗口的宽度以及当前窗口是否显示了滚动条,随后第二个IMAQ WindSize则设置窗口宽度比原窗口宽50像素,且滚动条的显示状态与原窗口相反。对这个例子来说,由于IMAQ WindSetup之前设置了窗口滚动条隐藏,因此最终显示的图像窗口包含滚动条。这种同一VI的两个不同实例实现完全不同的功能的情况正是由其Get/Set参数决定的。IMAQ WindSize、IMAQ WindMove也可采用类似的使用方法。

图4-28 外部窗口的属性读取和设置

使用外部窗口显示图像时,IMAQ WindDraw的使用时机极为重要。在图4-28所示的代码中,若去掉第二个IMAQ WindDraw并运行程序,会发现外部窗口中并无任何图像显示。这时因为,虽然第一次使用IMAQ WindDraw在窗口中绘制了图像,但此后IMAQ WindSize却重新更改了窗口宽度,而外部窗口并不自动重绘图像,因此必须再次通过代码重绘图像才能得到正确的图像显示。然而,如何才能让程序不断监测外部窗口的变化并进行自动重绘呢?这可以通过图4-29所示的IMAQ WindLastEvent来解决。

图4-29 IMAQ WindLastEvent原型

IMAQ WindLastEvent可以监测并返回图像显示窗口生成的各种事件以及与之绑定的事件数据,包括鼠标单击(Click)和双击(Double-Click)、用户在窗口中绘制ROI(Draw)、窗口移动(Move)、窗口缩放(Size)、滚动条滚动(Scroll)以及窗口激活(Activate)和关闭(Close)事件。Event List参数允许开发人员选择要监测所有这些事件还是其中一部分。一旦运行,它就会返回是否有被监测的事件发生,并会通过窗口编号、事件(Event)、工具(Tool)、坐标(Coordinates)和事件数据(Other Parameters)详细说明所发生事件的情况。

例如,当用户在窗口中绘制一个矩形ROI时,IMAQ WindLastEvent就会返回Draw事件,同时Tool参数告诉程序用户使用了矩形ROI工具,Coordinates数组中的前4项说明了矩形左上和右下两个点的坐标,而Other Parameters数组的前两项则说明了矩形的长和宽。根据这些返回的信息,开发人员可以进一步处理这些发生的事件。表4-11汇总了IMAQ WindLastEvent可监测的窗口事件及事件数据。

表4-11 IMAQ WindLastEvent可监测的窗口事件

一旦可以捕获外部图像显示窗口中发生的事件及其返回的事件数据,就可以在主程序中对这些事件进行处理。具体来说,IMAQ WindLastEvent的Event参数可以作为分支结构的索引来区分不同事件,然后在分支结构的不同分支中对各个事件分别进行处理。图4-30显示了一个IMAQ WindLastEvent创建的简易事件捕获器工作时的界面及其代码。程序先在主界面之外的一个独立窗口中显示一幅图像,窗口的ROI工具条也同时显示给用户进行测试。当用户选择了椭圆ROI工具并在独立的图像窗口中绘制ROI时,程序主界面就会显示捕获到的绘制ROI事件,同时与其相关的事件数据也会显示给用户。通过这个简易的事件捕获器,可以对表4-11中的各种外部窗口事件进行测试。

图4-30 简易IMAQ WindLastEvent事件捕获器

在上面程序代码中,我们看到外部图像显示窗口也可以和图像显示控件一样拥有一个绘制ROI的工具条。外部图像显示窗口的ROI工具条以浮动方式显示,其中的ROI工具使用方法与图像显示控件的ROI工具使用方法类似,用户可以使用它们直接在外部窗口中绘制ROI。在程序代码中,可以通过表4-12所列的VI控制外部窗口的浮动ROI工具条,包括配置工具条中可用的工具项,选中某个ROI工具,显示/隐藏、移动或关闭ROI工具条。这些VI的使用方法与相应的外部显示窗口显示/隐藏、移动和关闭VI的使用方法类似,均可使用Get/Set开关实现读取或设置两种功能。值得一提的是IMAQ WindToolsSelect,它可以在不显示浮动ROI工具条的情况下,通过参数为用户直接选中某个ROI工具。

表4-12 外部窗口的ROI工具条控制VI

除了让用户使用外部图像显示窗口和图像显示控件的ROI工具条,以交互的方式定义ROI之外,还有一些其他定义ROI的方法,如通过ROI生成器、程序代码以及图像遮罩定义ROI等,4.4节将对各种ROI的定义和控制方法进行总结。