3.6 位平面分解
将灰度图像中处于同一比特位上的二进制像素值进行组合,得到一幅二进制值图像,该图像被称为灰度图像的一个位平面,这个过程被称为位平面分解。例如,将一幅灰度图像内所有像素点上处于二进制位内最低位上的值进行组合,可以构成“最低有效位”位平面。
在8位灰度图中,每一个像素使用8位二进制值来表示,其值的范围在[0,255]之间。可以将其中的值表示为:
value=a7×27+a6×26+a5×25+a4×24+a3×23+a2×22+a1×21+a0×20
式中,ai的可能值为0或1。可以看出,各个ai的权重是不一样的,a7的权重最高,a0的权重最低。这代表a7的值对图像的影响最大,而a0的值对图像的影响最小。
通过提取灰度图像像素点二进制像素值的每一比特位的组合,可以得到多个位平面图像。图像中全部像素值的ai值所构成的位平面,称为第i个位平面(第i层)。在8位灰度图中,可以组成8个二进制值图像,即可以将原图分解为8个位平面。
根据上述分析,像素值中各个ai的权重是不一样的:
● a7的权重最高,所构成的位平面与原图像相关性最高,该位平面看起来通常与原图像最类似。
● a0权重最低,所构成的位平面与原图像相关性最低,该平面看起来通常是杂乱无章的。
借助按位与运算可以实现位平面分解。例如,有灰度图像O的像素值为:
其对应的二进制值为:
将所有像素的ai值进行组合,便会得到图像的8个位平面,如图3-9所示。
图3-9 位平面分解
图3-9中的各个位平面的构成如下。
● 图(a)是由图像O中每个像素的a0值(即从右边数第0个二进制位,第0个比特位)组成的,我们称之为第0个位平面,也可以称为第0层,即是由二进制位的第0位构成的。为了叙述和理解上的方便,其序号从0开始,也可以称为“最低有效位”位平面。
● 图(b)是由图像O中每个像素的a1值(即从右数第1个比特位)组成的,我们称之为第1个位平面(或第1层)。
● 图(c)是由图像O中每个像素的a2值(即从右数第2个比特位)组成的,我们称之为第2个位平面(或第2层)。
● 图(d)是由图像O中每个像素的a3值(即从右数第3个比特位)组成的,我们称之为第3个位平面(或第3层)。
● 图(e)是由图像O中每个像素的a4值(即从右数第4个比特位)组成的,我们称之为第4个位平面(或第4层)。
● 图(f)是由图像O中每个像素的a5值(即从右数第5个比特位)组成的,我们称之为第5个位平面(或第5层)。
● 图(g)是由图像O中每个像素的a6值(即从右数第6个比特位)组成的,我们称之为第6个位平面(或第6层)。
● 图(h)是由图像O中每个像素的a7值(即从右数第7个比特位)组成的,我们称之为第7个位平面(或第7层),也可以称为“最高有效位”位平面。
针对RGB图像,如果将R通道、G通道、B通道中的每一个通道对应的位平面进行合并,即可组成新的RGB彩色图像。例如,针对一幅RGB图像,将其R通道的第3个位平面、G通道的第3个位平面、B通道的第3个位平面进行合并,则可以构成一幅新的RGB彩色图像,我们称之为原始图像的第3个位平面。通过上述方式,可以完成彩色图像的位平面分解。
下面以灰度图像为例,介绍位平面分解的具体步骤。
1.图像预处理
读取原始图像O,获取原始图像O的宽度M和高度N。
2.构造提取矩阵
使用按位与操作能够很方便地将一个数值指定位上的数字提取出来。例如,在表3-12中,分别使用不同的提取因子F来提取数值N中的特定位。可以发现,提取因子F哪位上的值为1,就可以提取数值N中哪位上的数字。
表3-12 位值提取示例
根据上述分析结果,建立一个值均为2n的Mat作为提取矩阵(数组),用来与原始图像进行按位与运算,以提取第n个位平面。
提取矩阵Mat内可能的值如表3-13所示。
表3-13 Mat内可能的值
3.提取位平面
将灰度图像与提取矩阵进行按位与运算,得到各个位平面。
将像素值与一个值为2n的数值进行按位与运算,能够使像素值的第n位保持不变,而将其余各位均置零。因此,通过像素值与特定值的按位与运算,能够提取像素值的指定二进制位的值。同理,通过按位与运算,能够提取图像的指定位平面。
例如,有一个像素点的像素值为219,要提取其第4个二进制位的值,即提取该像素值的第4位信息(序号从0开始)。此时,需要借助的提取值是“24=16”,具体的运算如表3-14所示。
表3-14 提取像素值示例
从表3-14可以看到,通过将像素值219与提取值24的二进制值进行按位与运算,提取到了像素值219第4位上的二进制数字“1”。这是因为在24的二进制表示中,只有第4位上的数字为1,其余各位的数字都是0。在像素值219与提取值24的二进制值进行按位与运算时:
● 像素值219第4位上的数字“1”与提取值24第4位上的数字“1”进行与操作,数字“1”被保留。
● 像素值219其他位上的数字与提取值24其他位上的数字“0”进行与操作,所以都会变为0。
在针对图像的位平面提取中,例如有图像O,其像素值为:
其对应的二进制形式标记为RB,具体如下:
如果想提取其中的第3个位平面,则需要建立元素值均为23的数组BD,其中的值全部为8(即23),具体如下:
将数组BD所对应的二进制形式标记为BT,具体为:
将RB与BT进行按位与运算,得到RE,具体为:
将RE所对应的十进制形式标记为RD,具体为:
【提示】提取位平面也可以通过将二进制像素值右移指定位,然后对2取模得到。例如,要提取第n个位平面,则可以将像素向右侧移动n位,然后对2取模,就可以得到第n个位平面。
4.阈值处理
通过计算得到的位平面是一个二值图像,如果直接将上述得到的位平面显示出来,则会得到一张近似黑色的图像。这是因为默认当前显示的图像是8位灰度图,而当其中的像素值较小时,显示的图像就会是近似黑色的。例如,在图像RD中,最大的像素值是8,因此几乎为纯黑色。要想让8显示为白色,必须将8处理为255。
也就是说,每次提取位平面后,要想让二值位平面能够以黑白颜色显示出来,就要将得到的二值位平面进行阈值处理,将其中大于零的值处理为255。
例如,将得到的位平面RD进行阈值处理,将其中的8调整为255,具体语句为:
mask=RD[:, :, i]>0 RD[mask]=255
首先,使用mask=RD[:, :, i]>0对RD进行处理:
● 将RD中大于0的值处理为逻辑值真(True)。
● 将RD中小于或等于0的值处理为逻辑值假(False)。
按照上述处理,得到的mask为:
接下来,使用RD[mask]=255,将RD中对应“mask中逻辑值为真”位置上的值替换为255。在阈值调整后的位平面RD中,原来为8的值被替换为255,具体如下:
需要说明的是,在OpenCV中,提供了专门的函数用来进行阈值处理。关于阈值处理的相关内容会在第6章进行详细介绍。
5.显示图像
完成上述处理后,可以将位平面显示出来,直观地观察各个位平面的具体情况。
【例3.13】编写程序,观察灰度图像的各个位平面。
根据题目要求,编写代码如下:
import cv2 import numpy as np lena=cv2.imread("lena.bmp",0) cv2.imshow("lena", lena) r, c=lena.shape x=np.zeros((r, c,8), dtype=np.uint8) for i in range(8): x[:, :, i]=2**i r=np.zeros((r, c,8), dtype=np.uint8) for i in range(8): r[:, :, i]=cv2.bitwise_and(lena, x[:, :, i]) mask=r[:, :, i]>0 r[mask]=255 cv2.imshow(str(i), r[:, :, i]) cv2.waitKey() cv2.destroyAllWindows()
在本例中,通过两个循环提取了灰度图像的各个位平面,具体说明如下。
● 使用x=np.zeros((r, c,8), dtype=np.uint8)语句设置一个用于提取各个位平面的提取矩阵。该矩阵是“r×c×8”大小的,其中r是行高,c是列宽,8表示共有8个通道。r、c的值来源于要提取的图像的行高、列宽。矩阵x的8个通道分别用来提取灰度图像的8个位平面。例如,x[:, :,0]用来提取灰度图像的第0个位平面。
● 在第1个for循环中,使用x[:, :, i]=2**i语句设置用于提取各个位平面的提取矩阵的值。
● 在第2个for循环中,实现了各个位平面的提取、阈值处理和显示。
运行上述程序,得到如图3-10所示的图像,其中:
图3-10 位平面分解效果图
● 图(a)是原始lena图像。
● 图(b)是第0个位平面,第0个位平面位于8位二进制值的最低位,其权重最低,对像素值的影响最小,与lena图像的相关度也最低,所以显示出来的是一幅杂乱无章的图像。
● 图(c)是第1个位平面。
● 图(d)是第2个位平面。
● 图(e)是第3个位平面。
● 图(f)是第4个位平面。
● 图(g)是第5个位平面。
● 图(h)是第6个位平面。
● 图(i)是第7个位平面,第7个位平面位于8位二进制值的最高位,其对像素值的影响最大。第7位二进制值在8位二进制数中权重最高,与lena图像的相关度最高。所以,第7个位平面是与原始图像最接近的二值图像。