3.3.1 按位与运算

在与运算中,当参加与运算的两个逻辑值都是真时,结果才为真。其逻辑关系可以类比图3-4所示的串联电路,只有当两个开关都闭合时,灯才会亮。

图3-4 与运算类比电路

表3-2对与运算算子的不同情况进行了说明,表中使用“and”表示与运算。

表3-2 与运算

按位与运算是指将数值转换为二进制值后,在对应的位上逐位进行与运算。表3-3展示了两个数值进行按位与运算的示例。表中最后一列,展示了将十进制值转换为二进制后,数值1与数值2在对应位上,逐位进行按位与运算的结果。例如,在最低位上(最右边一位),数值1对应的值为“0”,数值2对应的值为“1”,与运算的结果为“0”。

表3-3 按位与运算

在OpenCV中,可以使用cv2.bitwise_and()函数来实现按位与运算,其语法格式为

其中:

● dst表示与输入值具有同样大小的array输出值。

● src1表示第一个array或scalar类型的输入值。

● src2表示第二个array或scalar类型的输入值。

● mask表示可选操作掩码,8位单通道array。

按位与操作有如下特点:

● 将任何数值N与数值0进行按位与操作,都会得到数值0。

● 将任何数值N(这里仅考虑8位值)与数值255(8位二进制数是1111 1111)进行按位与操作,都会得到数值N本身。

可以通过表3-4观察数值N(表中是219)与特殊值0和255进行按位与运算的结果。

表3-4 与特殊值0和255进行按位与运算

根据上述特点,可以构造一幅掩膜图像M,掩膜图像M中只有两种值:一种是数值0,另外一种是数值255。将该掩膜图像M与一幅灰度图像G进行按位与操作,在得到的结果图像R中:

● 与掩膜图像M中的数值255对应位置上的值,来源于灰度图像G。

● 与掩膜图像M中的数值0对应位置上的值为零(黑色)。

通过掩膜图像,可以非常方便地提取出一幅图像中的ROI。

第13章将从另外一个角度对上述情况进行说明,以帮助大家更好地理解掩膜及处理方式。

【例3.7】使用数组演示与掩膜图像的按位与运算。

根据题目要求,编写代码如下:

运行上述程序,输出结果如下:

从程序可以看出,数组c来源于数组a与数组b的按位与操作。运算结果显示,对于数组c内的值,与数组b中数值255对应位置上的值来源于数组a;与数组b中数值0对应位置上的值为0。

【例3.8】构造一个掩膜图像,使用按位与运算保留图像中被掩膜指定的部分。

在本例中,我们构造一个掩膜图像,保留图像lena的头部。

根据题目要求,编写代码如下:

运行上述程序,输出结果如图3-5所示,图3-5(a)是原始图像lena,图3-5(b)是掩膜图像,图3-5(c)是按位与结果图像,可以看到,被掩膜指定的头部图像被保留在了运算结果中。

图3-5 【例3.8】程序的运行结果

除了需要对灰度图像进行掩膜处理,还经常需要针对BGR模式的彩色图像使用掩膜提取指定部分。由于按位与操作要求参与运算的数据有相同的通道,所以无法直接将彩色图像与单通道的掩膜图像进行按位与操作。一般情况下,可以通过将掩膜图像转换为BGR模式的彩色图像,让彩色图像与掩膜图像进行按位与操作,实现掩膜运算。

【例3.9】构造一个掩膜图像,使用按位与操作保留彩色图像内被掩膜所指定的部分。

根据题目要求,编写代码如下:

运行上述程序,输出结果如图3-6所示,其中图3-6(a)是原始图像,图3-6(b)是掩膜图像,图3-6(c)是原始图像和掩膜图像按位与后提取的图像。由于本书为黑白印刷,所以为了更好地观察运行效果,请大家亲自上机验证程序。

图3-6 【例3.9】程序的运行结果

同时,程序还会显示如下结果:

例3.8和例3.9,唯一的不同在于要处理的图像a不同。它们读取的是同一幅彩色图像“lenacolor.png”。但是,在例3.8中,采用“a=cv2.imread("lenacolor.png",0)”,读取到的a是一幅灰度图像;在例3.9中,采用“a=cv2.imread("lenacolor.png",1)”,读取到的a是一幅彩色图像。

需要注意的是,在上述两个例题中,都采用“b=np.zeros(a.shape,dtype=np.uint8)”,让b的尺度大小(长度、宽度、通道数)为“a.shape”(等于a的尺度大小)。所以,彩色图像和单通道的灰度图像的处理,看起来是没有差别的。但是,需要额外注意的是,如果直接使用数值的方式指定b的尺度大小,那么在处理灰度图像和彩色图像时,就需要注意二者的区别,要将b指定为不同的尺度大小以适应参与运算的图像a(灰度图像或彩色图像)的尺度大小。例如,在处理灰度图像时,需要将b指定为与灰度图像尺度大小一致,使用语句为“b=np.zeros((512,512),dtype=np.uint8)”;在处理彩色图像时,需要将b指定为与彩色图像尺度大小一致,使用语句为“b=np.zeros((512,512,3),dtype=np.uint8)”。