- 计算机视觉40例从入门到深度学习(OpenCV-Python)
- 李立宗
- 4244字
- 2024-02-27 15:48:29
1.1 图像表示基础
本节将介绍图像的表示方式。很多算法的思想都来源于生活实践,图像处理算法及表示也是如此。从现实生活的角度去理解算法,能够帮助我们快速地理解算法的含义及实现思路。对于很多非常抽象的算法、概念,如果只去理解其本身,那么可能百思而不得其解。但是,如果从思想来源入手,找到其在生活中对应的实例,那么将能快速理解其内涵并对其进行应用。
1.1.1 艺术与生活
小时候,我经常用瓜子摆一个小动物或者几个简单的字。在生活中,也可以看到类似的作品。例如,很多人会在家里绣制十字绣。我堂姐曾绣制了一幅百寿图,该绣品由一百个不同字体的“寿”字组成,饱含着她对父母健康长寿的期望。有些大学生在军训或者毕业时,通过站成不同的队列,来组成表达他们感情的文字,在经过组织后还可以实现不同文字内容的切换,从而实现动画效果。如今,越来越多的艺术家专注于像素艺术画的创造,他们用各种素材(如键盘的键帽等)拼凑出具有较好艺术价值的人像,如让许多人在广场上排列出玛丽莲·梦露的肖像。
上述图像都是由一个个不同颜色的对象构成的。
数字图像的存储、显示与十字绣等作品的制作具有异曲同工之妙,数字图像是由一个又一个的点构成的,这些点被称为像素。
1.1.2 数字图像
计算机使用不同的数值来表示不同的颜色。例如,图1-1左侧是一幅二值图像,该图像是由64个像素点构成的,这些像素点分为两种颜色,即黑色和白色。该图像在被存储到计算机中时,白色的像素点被存储为“1”,黑色的像素点被存储为“0”,如图1-1右侧图所示。在将右侧数据从计算机内读取出来显示时,数值“0”被显示为黑色像素点,数值“1”被显示为白色像素点,如图1-1左侧图像所示。
图1-1 二值图像示例
在图1-1中,仅仅有8×8个像素点,比较简单,通常用来表示数字、字母等简单信息,被广泛应用在仪表盘等场景下。如果图像包含更多像素点,那么图像将能够呈现更细微的变化与差别。例如,图1-2的左侧图像,在计算机中可以存储为如图1-2右侧图像所示的形式。图1-2左侧图像包含512×512个像素点,用由512×512个0和1构成的一个矩阵来表示。由于512×512个0和1无法直接在书中体现,因此选取图1-2左侧图像的部分区域进行说明。从图1-2左侧图像中,选取一个9像素×9像素大小的区域,其在计算机内的存储形式如图1-2右侧图像所示;在需要显示时,可以从计算机中读取图1-2右侧图像所示数据,其将显示为图1-2左侧图像形式。
图1-2 图像显示
通过观察可以发现,表示一幅图像的像素点越多,图像呈现的细节信息越丰富,图像越逼真。这个衡量图像清晰度的重要标准被称为分辨率。通常情况下,图像的分辨率越高,单位面积内所包含的像素点越多,图像越清晰。
二值图像仅仅能够表示黑白两种颜色,色彩比较单一,因此呈现的信息不够丰富。如果使用更多的颜色来呈现图像,就可以让图像具有更丰富的层次。例如,图1-3左侧图像不再仅有黑白两种颜色,而是具有更多的灰度级。图1-3左侧图像的色彩如图1-3右侧图像所示,除了纯黑、纯白还包含非常多不同程度的灰色。
图1-3 图像色彩范围
通常情况下,使用一个字节,即8个二进制位,来表示一个像素点。一个8位的二进制数能够表示的数据范围是0000 0000~1111 1111,即0~28,也就是[0,255]。因此使用8位二进制数能够表示256种不同的颜色,这里的颜色为黑、白、灰三种。
二值图像指仅具有黑色、白色两种不同颜色的图像。上述具有更多灰度级的图像被称为灰度图像。
一般情况下,使用灰度级来表示色彩的范围,使用8位二进制数表示的灰度图像具有256个灰度级。
通常所说的灰度图像,是指上述具有256个灰度级的图像。一般用8位二进制数表示的灰度图像,被称为8位位图。
在灰度图像中,使用数值“0”表示纯黑色,使用数值“255”表示纯白色,使用其他值分别表示不同程度的灰色。数值越小,灰度越深;数值越大,灰度越浅。灰度值与色彩示意图如图1-4所示。
图1-4 灰度值与色彩示意图
例如,在图1-5中,左侧图像是由512×512个像素点组成的图像。选取其中大小为9像素×9像素的区域,其内部的像素值如图1-5右侧图像所示。在存储图像时,将类似于图1-5中右侧图像中的数值保存在计算机内;在显示图像时,从计算机中读取类似于图1-5右侧图像的数值,并将不同的数值按照图1-4处理为不同的颜色,最终显示为图1-5左侧图像。
图1-5 灰度图像示例
1.1.3 二值图像的处理
二值图像仅有黑色和白色,因此可以仅使用一个比特位来表示一个像素点,用数值“1”表示白色,用数值“0”表示黑色。
在计算机中,字节是存储的基本单位。与此相对应,8位位图是一种应用最广泛的图像。因此,在实践中,为了处理上的方便及一致性,通常用8位位图来表示二值图像。
在8位位图构成的灰度图像中,用数值“255”表示白色,用数值“0”表示黑色,其他数值分别表示深浅不同的灰色。
在使用包含256个灰度级的8位位图来表示仅包含黑色和白色的二值图像时,用数值“255”表示白色,用数值“0”表示黑色。在使用包含256个灰度级的8位位图来表示的二值图像中,除了数值“0”和数值“255”,不存在其他值。因此图1-6左侧图像的表示形式不再使用图1-6中间图像所示的形式,而是使用图1-6右侧图像所示的“0”和“255”的形式。
图1-6 二值图像的表示
在实践中,通常会将其他形式的图像(如灰度图像)处理为二值图像再进行运算。一方面是由于二值图像运算更简单方便,另一方面是由于二值图像能够保留原始图像(如灰度图像)中的重要特征信息。因此,二值图像是图像处理过程中的关键图像,在实践中发挥着非常重要的作用。
1.1.4 像素值的范围
通常情况下,采用一个字节来描述灰度图像中一个像素点的像素值。一个字节表示的范围是[0,255]。在处理图像的过程中,像素点的像素值的处理结果可能会超过255,此时应该如何处理该值呢?
先来看看现实生活中的情况。实际上,在显示数据时,存在如下两种不同的处理方式。
● 取模处理:也可以称为“循环取余”。现实生活中的电表、水表、机械手表等显示数据使用的都是取模处理方式。这些表的终点和起点是重叠的,到达终点后,就是一个新的起点。例如,墙上的挂钟仅仅能够显示1~12点,当13点时,实际显示的是1点,而不是13点。电表、水表等以机械方式进行计数的表与此类似,在显示了“9999”后,继续从“0000”开始计数。
● 饱和处理:把越界的数值处理为最大值,也被称为“截断处理”。汽车仪表盘等场景使用的是饱和处理方式。当汽车速度超过仪表盘能显示的最大值时,仪表盘显示的就是最大值,不会从0开始重新计数。如果汽车仪表盘能显示的最高值是200km/h,那么车速在达到300km/h时,汽车仪表盘也只能显示200km/h。
实践中,上述两种方式都有广泛应用。在图像处理过程中,也常采用上述两种方式对图像的运算结果进行处理。下面以8位位图为例来进行说明。
● 取模处理:如果像素点的像素值超过255,则将处理结果对255取模,并将得到的值作为运算结果。当然,在不超过255时,取模与否结果都是自身。如果在进行取模处理前,某个像素点的像素值为258,那么其对255取模得到的结果为258%255=3,即该像素点的最终像素值为3。其中,符号“%”表示取模运算。如果在进行取模处理前,某个像素点的像素值为251,那么其对255取模得到的结果为251%255=251,即得到的结果仍是251。综上所述,在取模处理时,如果某像素点的像素值是N,那么其结果为N%255。具体可以表示为
result=mod(ov,255)
其中,ov为原始值,mod(a,b)表示将a对b取模。
● 饱和处理:将超过255的像素值处理为255,小于或等于255的像素值保持不变。如果在进行饱和处理前,某个像素点的像素值为258,那么其将被处理为255。如果在进行饱和处理前,某个像素点的像素值为251,小于255,就不需要进行额外处理,得到的结果仍旧是251,具体可以表示为
其中,ov表示在进行饱和处理前经过计算得到的需要进行饱和处理的值。
在某些情况下,希望体现像素值更加细腻的差异,不再满足于仅使用256个灰度级来表示颜色。这时,就需要使用更多的二进制位来表示像素点的像素值。例如,采用16个二进制位来表示一个像素点。此时,图像具有216(65536)个灰度级,每一个像素点的像素值范围是[0,216-1],共有216种可能值。
在8位位图的灰度图像中,数值“0”表示纯黑色,数值“255”表示纯白色;而数值[1,127]表示颜色较深的灰色,数值[128,254]表示颜色较浅的灰色。同样,在16位位图中,数值“0”表示纯黑色,数值“216-1”表示纯白色;而数值表示颜色较深的灰色、数值表示颜色较浅的灰色。8位位图和16位位图的颜色示意图如图1-7所示。
图1-7 8位位图和16位位图的颜色示意图
有时需要将针对8位位图进行计算得到的处理结果图像R转换为16位位图。如果在将图像R转换为16位位图后,得到的新的像素值正好均匀分布在16位位图的范围[0,216-1]内,就不需要做任何额外处理了。
但是,在实践中往往会出现需要进行额外处理的情况。例如,在对一个8位位图进行某种运算处理后得到新的图像R,图像R的像素值在[0,1000]内。此时,如果想保留图像R内像素值之间的差异,就不能再使用8位位图了。因为8位位图仅能够表示256个灰度级,不能够完全体现出当前分布在[0,1000]内的像素值的差异情况。要体现出处理结果中[0,1000]内像素值的差异情况,只能选用16位位图。
需要注意的是,在转换了数值的表示范围后,要对数值进行合适的处理才能让图像正常显示。例如,上述处理结果图像R的像素值分布在[0,1000]范围内,由于这些像素值都分布在16位位图的像素值[0,216-1]范围中值较小的范围内,因此对应的是黑色或颜色较深的灰色。此时,需要采用某种方式将上述分布在[0,1000]内的值调整(映射)到[0,216-1]范围内,以让图像正常显示,保证后续的处理。像素值的调整方式有直方图均衡化、归一化等。
【注意】数据范围不同导致的图像不能正常显示,或者不能得到正确处理是一种比较常见的错误。
1.1.5 图像索引
简单来理解,数字图像在计算机中是存储在一个矩阵(数组)内的。矩阵中的每个元素都有一个位置值,该位置值用来表示元素所在位置的行号和列号。这个位置通常被称为索引。例如,在图1-8中,左上角的像素点的索引为(0,0),索引中第1个数值“0”表示该像素点在第0行,第2个数值“0”表示该像素点在第“0”列。
图1-8 像素点的索引表示方式
有时还需要使用坐标系表示OpenCV内的图像的位置。需要注意的是,OpenCV中图像坐标原点在其左上角,该点坐标值为(0,0)。自原点向右,x值不断增加;自原点向下,y值不断增加。OpenCV中的图像坐标如图1-9所示。
图1-9 OpenCV中的图像坐标
坐标和矩阵的应用场景不同。在运算中,需要额外注意坐标和矩阵之间的关系。在图像处理中经常用到图像的行(row)、列(column)、宽度(width)、高度(height)信息。图像尺度参数示意图如图1-10所示,由此图可知这些信息和我们日常理解的含义没有差异。
图1-10 图像尺度参数示意图