![OpenCV轻松入门:面向Python](https://wfqqreader-1252317822.image.myqcloud.com/cover/910/26297910/b_26297910.jpg)
3.3 按位逻辑运算
逻辑运算是一种非常重要的运算方式,图像处理过程中经常要按照位进行逻辑运算,本节介绍OpenCV中的按位逻辑运算,简称位运算。
在OpenCV内,常见的位运算函数如表3-1所示。
表3-1 常见的位运算函数
![](https://epubservercos.yuewen.com/53BA2F/14737439604468406/epubprivate/OEBPS/Images/Figure-0060-0040.jpg?sign=1738805435-jVUida8Um7Dlx63pC5s7UrJHRDR5W9eR-0-87df1ea02d7e677364c73522b292e101)
3.3.1 按位与运算
在与运算中,当参与与运算的两个逻辑值都是真时,结果才为真。其逻辑关系可以类比图3-4所示的串联电路,只有当两个开关都闭合时,灯才会亮。
![](https://epubservercos.yuewen.com/53BA2F/14737439604468406/epubprivate/OEBPS/Images/Figure-0060-0041.jpg?sign=1738805435-bqhAJFf3VlnIDfLPZaL28Xj8DiI2jEMB-0-f8df307aa363d9fabdb575eb52319247)
图3-4 与运算类比电路
表3-2对与运算算子的不同情况进行了说明,表中使用“and”表示与运算。
表3-2 与运算
![](https://epubservercos.yuewen.com/53BA2F/14737439604468406/epubprivate/OEBPS/Images/Figure-0060-0042.jpg?sign=1738805435-3LMurnsNII4RjYwrMDCMe7lFXgDWpSEt-0-93b9cb23776680cbd744ca9861e508e4)
按位与运算是指将数值转换为二进制值后,在对应的位置上进行与运算。例如,表3-3展示了两个数值进行按位与运算的示例。
表3-3 按位与运算
![](https://epubservercos.yuewen.com/53BA2F/14737439604468406/epubprivate/OEBPS/Images/Figure-0060-0043.jpg?sign=1738805435-CAFbDPdU7eC70KviWxeLUr1kAHs0fiYe-0-ea213372125c6839bf540cee38f7dfb7)
在OpenCV中,可以使用cv2.bitwise_and()函数来实现按位与运算,其语法格式为:
dst = cv2.bitwise_and( src1, src2[, mask]] )
式中:
● dst表示与输入值具有同样大小的array输出值。
● src1表示第一个array或scalar类型的输入值。
● src2表示第二个array或scalar类型的输入值。
● mask表示可选操作掩码,8位单通道array。
按位与操作有如下特点:
● 将任何数值N与数值0进行按位与操作,都会得到数值0。
● 将任何数值N(这里仅考虑8位值)与数值255(8位二进制数是11111111)进行按位与操作,都会得到数值N本身。
可以通过表3-4观察数值N(表中是219)与特殊值0和255进行按位与运算的结果。
表3-4 与特殊值0和255进行按位与运算
![](https://epubservercos.yuewen.com/53BA2F/14737439604468406/epubprivate/OEBPS/Images/Figure-0061-0044.jpg?sign=1738805435-DogyhgMqZtZcupLtNHd24XXoWH7DdL88-0-d1e2f0956f273296b89efbe4c3ee89fa)
根据上述特点,可以构造一幅掩模图像M,掩模图像M中只有两种值:一种是数值0,另外一种是数值255。将该掩模图像M与一幅灰度图像G进行按位与操作,在得到的结果图像R中:
● 与掩模图像M中的数值255对应位置上的值,来源于灰度图像G。
● 与掩模图像M中的数值0对应位置上的值为零(黑色)。
第13章将从另外一个角度对上述情况进行说明,以帮助大家更好地理解掩模及处理方式。
【例3.7】使用数组演示与掩模图像的按位与运算。
根据题目要求,编写代码如下:
import cv2 import numpy as np a=np.random.randint(0,255, (5,5), dtype=np.uint8) b=np.zeros((5,5), dtype=np.uint8) b[0:3,0:3]=255 b[4,4]=255 c=cv2.bitwise_and(a, b) print("a=\n", a) print("b=\n", b) print("c=\n", c)
运行上述程序,输出结果如下:
a= [[ 39177191 66179] [109 28 7 17118] [241191 32 72202] [229 62 9 65187] [103 65207 45121]] b= [[255255255 0 0] [255255255 0 0] [255255255 0 0] [ 0 0 0 0 0] [ 0 0 0 0255]] c= [[ 39177191 0 0] [109 28 7 0 0] [241191 32 0 0] [ 0 0 0 0 0] [ 0 0 0 0121]]
从程序可以看出,数组c来源于数组a与数组b的按位与操作。运算结果显示,对于数组c内的值,与数组b中数值255对应位置上的值来源于数组a;与数组b中数值0对应位置上的值为0。
【例3.8】构造一个掩模图像,使用按位与运算保留图像中被掩模指定的部分。
在本例中,我们构造一个掩模图像,保留图像lena的头部。
根据题目要求,编写代码如下:
import cv2 import numpy as np a=cv2.imread("lena.bmp",0) b=np.zeros(a.shape, dtype=np.uint8) b[100:400,200:400]=255 b[100:500,100:200]=255 c=cv2.bitwise_and(a, b) cv2.imshow("a", a) cv2.imshow("b", b) cv2.imshow("c", c) cv2.waitKey() cv2.destroyAllWindows()
运行上述程序,输出结果如图3-5所示,左图是原始图像lena,中间的图是掩模图像,右图是按位与结果图像,可以看到,被掩模指定的头部图像被保留在了运算结果中。
![](https://epubservercos.yuewen.com/53BA2F/14737439604468406/epubprivate/OEBPS/Images/Figure-0062-0045.jpg?sign=1738805435-5fiJLJ5Zm69AYRlA4rZaPpesRQJa1Ody-0-371fff2f8e3c3514f1f49175ef54e04f)
图3-5 【例3.8】程序的运行结果
除了需要对灰度图像进行掩模处理,还经常需要针对BGR模式的彩色图像使用掩模提取指定部分。由于按位与操作要求参与运算的数据有相同的通道,所以无法直接将彩色图像与单通道的掩模图像进行按位与操作。一般情况下,可以通过将掩模图像转换为BGR模式的彩色图像,让彩色图像与掩模图像进行按位与操作,实现掩模运算。
【例3.9】构造一个掩模图像,使用按位与操作保留图像内被掩模所指定的部分。
根据题目要求,编写代码如下:
import cv2 import numpy as np a=cv2.imread("lena.bmp",1) b=np.zeros(a.shape, dtype=np.uint8) b[100:400,200:400]=255 b[100:500,100:200]=255 c=cv2.bitwise_and(a, b) print("a.shape=", a.shape) print("b.shape=", b.shape) cv2.imshow("a", a) cv2.imshow("b", b) cv2.imshow("c", c) cv2.waitKey() cv2.destroyAllWindows()
运行上述程序,输出结果如图3-6所示,其中左图是原始图像,中间的图是掩模图像,右图是原始图像和掩模图像按位与后提取的图像。由于本书为黑白印刷,所以为了更好地观察运行效果,请大家亲自上机运行程序。
![](https://epubservercos.yuewen.com/53BA2F/14737439604468406/epubprivate/OEBPS/Images/Figure-0063-0046.jpg?sign=1738805435-SBt8ymbLySgHF0zLEIZGUxVMxTsXlFJy-0-31af91abd5a582213251203471cb25d9)
图3-6 【例3.9】程序的运行结果
同时,程序还会显示如下结果:
a.shape= (512, 512, 3) b.shape= (512, 512, 3)
3.3.2 按位或运算
或运算的规则是,当参与或运算的两个逻辑值中有一个为真时,结果就为真。其逻辑关系可以类比为如图3-7所示的并联电路,两个开关中只要有任意一个闭合时,灯就会亮。
![](https://epubservercos.yuewen.com/53BA2F/14737439604468406/epubprivate/OEBPS/Images/Figure-0064-0047.jpg?sign=1738805435-t0y8GM3Ok5NVW50ZMm2Gw2sdVvjs4lBb-0-44a4ff79ecd3b9facb0af7751a29ca5a)
图3-7 或运算类比电路图
表3-5对参与或运算的算子的不同情况进行了说明,表中使用“or”表示或运算。
表3-5 或运算
![](https://epubservercos.yuewen.com/53BA2F/14737439604468406/epubprivate/OEBPS/Images/Figure-0064-0048.jpg?sign=1738805435-VvF7VevJXV8JVQz2yary56bpzrAmiH3N-0-af37ecfe937365baef45b6d90a2012e7)
按位或运算是指将数值转换为二进制值后,在对应的位置上进行或运算。例如,表3-6展示了两个数值进行按位或运算的示例。
表3-6 按位或运算
![](https://epubservercos.yuewen.com/53BA2F/14737439604468406/epubprivate/OEBPS/Images/Figure-0064-0049.jpg?sign=1738805435-bu2YsehSnmxlK3puS8rOMNO99wmFl6ZD-0-9b56c3db741f71a79a8ec737ff1a1d3b)
在OpenCV中,可以使用cv2.bitwise_or()函数来实现按位或运算,其语法格式为:
dst = cv2.bitwise_or( src1, src2[, mask]] )
式中:
● dst表示与输入值具有同样大小的array输出值。
● src1表示第一个array或scalar类型的输入值。
● src2表示第二个array或scalar类型的输入值。
● mask表示可选操作掩码,8位单通道array值。
3.3.3 按位非运算
非运算是取反操作,满足如下逻辑:
● 当运算数为真时,结果为假。
● 当运算数为假时,结果为真。
表3-7对参与运算算子的不同情况进行了说明,表中使用“not”表示非运算。
表3-7 非运算
![](https://epubservercos.yuewen.com/53BA2F/14737439604468406/epubprivate/OEBPS/Images/Figure-0064-0050.jpg?sign=1738805435-EDvgH8rURKtyOZr2QAQzIXu4aKFukSz5-0-fa0ef800b651d38cef9cc1f81745cb1f)
按位非运算是指将数值转换为二进制值后,在对应的位置上进行非运算。例如,表3-8展示了按位非运算的示例。
表3-8 按位非运算
![](https://epubservercos.yuewen.com/53BA2F/14737439604468406/epubprivate/OEBPS/Images/Figure-0065-0051.jpg?sign=1738805435-rnrAXWy41AjwH7QqyCnRVtSRC7s8zLdH-0-256e61e1a690434cd3e101f83b65d581)
在OpenCV中,可以使用函数cv2.bitwise_not()来实现按位取反操作,其语法格式为:
dst = cv2.bitwise_not( src[, mask]] )
式中:
● dst表示与输入值具有同样大小的array输出值。
● src表示array类型的输入值。
● mask表示可选操作掩码,8位单通道array值。
3.3.4 按位异或运算
异或运算也叫半加运算,其运算法则与不带进位的二进制加法类似,其英文为“exclusive OR”,因此其函数通常表示为xor。
表3-9对参与异或运算的算子的不同情况进行了说明,其中“xor”表示异或运算。
表3-9 异或运算
![](https://epubservercos.yuewen.com/53BA2F/14737439604468406/epubprivate/OEBPS/Images/Figure-0065-0052.jpg?sign=1738805435-FQgrZLcf2WNkIk15lsNZ2EB368WQNrlP-0-3488e5bd549340281e8b653ad2f813b7)
按位异或运算是指将数值转换为二进制值后,在对应的位置上进行异或运算。例如,表3-10展示了两个数值进行按位异或运算的示例。
表3-10 按位异或运算
![](https://epubservercos.yuewen.com/53BA2F/14737439604468406/epubprivate/OEBPS/Images/Figure-0065-0053.jpg?sign=1738805435-JXO0X1IAYxU11KVbEGYqDNrSVgpO0bkH-0-b41ac104529c0bee122b3b2c2db40dc2)
在OpenCV中,可以使用函数cv2.bitwise_xor()来实现按位异或运算,其语法格式为:
dst = cv2.bitwise_xor( src1, src2[, mask]] )
式中:
● dst表示与输入值具有同样大小的array输出值。
● src1表示第一个array或scalar类型的输入值。
● src2表示第二个array或scalar类型的输入值。
● mask表示可选操作掩码,8位单通道array值。