介绍
是对二进制数据进行“与”操作,即对图像(灰度图像或彩色图像均可)每个像素值进行二进制“与”操作,1&1=1,1&0=0,0&1=0,0&0=0
源码:
bitwise_and(src1, src2, dst=None, mask=None)
参数:
-
src1、src2:为输入图像或标量,标量可以为单个数值或一个四元组
-
dst:可选输出变量,如果需要使用非None则要先定义,且其大小与输入变量相同
-
mask:图像掩膜,可选参数,为8位单通道的灰度图像,用于指定要更改的输出图像数组的元素,即输出图像
代码实列讲解:
import cv2 as cv
import numpy as np
# 创建两个三位数组,为了方便观看,数值已经是最小的了,在小一点就体现不出来效果了
a = np.random.randint(0, 10, size=(2, 2, 2))
b = np.random.randint(0, 10, size=(2, 2, 2))
print('---------- a ---------')
print(a)
print(a[0][1])
print(a.shape)
print('---------- b ---------')
print(b)
print(b.shape)
# 创建掩膜 也是最小的,记住最后转换数据类型,np.uint8,不然会报错
# error: (-215:Assertion failed) (mtype == CV_8U || mtype == CV_8S) && _mask.sameSize(*psrc1) in function 'cv::binary_op'
# 数组中的 1 就是对应在 inRange() 方法中,满足颜色条件的 255,而不满足颜色条件的则是 0 。
# 这个方法就不具体细讲了,可以理解为 ---> 1 为 True,0 为 False
# 其实改成其他值也一样,在python当中,只要不为0的数值都是True, 0则是False
mask = np.array([[1,0], [0, 0]], dtype=np.uint8) # mask = np.array([[True,False], [False, False]], dtype=np.uint8)
print('---------- mask ---------')
print(mask)
print(mask.shape)
print(mask[0][1])
# 进行与运算
c = cv.bitwise_and(a, b, mask=mask) # 添加掩膜
d = cv.bitwise_and(a, b) # 不加掩膜
print('---------- c ---------')
print(c)
print(c.shape)
print('---------- d ---------')
print(d)
print(d.shape)
"""
a: 1 1 1
b: 1 0 1
"""
结果如下
途中标注了编号及画框的位置就是接下来要讲的和注意的地方
首先讲一下,在没有添加掩膜的情况与运算结果,也就是
没有掩膜的编号6:
a 与 b:
结果:
运算的具体过程:
a的每一位数与b中的每一位数进行二进制的与运算。
原数 | 二进制 | 过程(相同的为True,不相同的为False) | 结果 |
a:5 b:6 | a:101 b:110 | 二进制:100 十进制:4 | |
a:7 b:5 | a:111 b:101 | 二进制:101 十进制:5 |
总结:
在没有添加掩膜的情况下,就是指单纯的把两个数组中的每一位元素对应进行与运算
以此类推
有掩膜的编号5:
结果:
步骤基本与上面相同,唯一的区别在于添加掩膜后的作用是什么?
从结果上来看:
把上面的图取下来
掩膜数组中第一个元素为255,其余位置是 0。mask[0][0]的元素位置为255,所以只会对 a[0][0] 与b[0][0],进行运算,也就是说只有满足掩膜元素为True的a,b对应位置上元素才会进行与运算,不满足的都为 0
(其实改成其他值也一样,在python当中,只要不为0的数值都是True, 0则是False。mask = np.array([[True, False], [False, False]], dtype=np.uint8) 把掩膜换成这样也是可以的)
总结:
添加掩膜后:
mask[ i ][ j ] = True
a[ i ][ j ] 与 b[ i ][ j ] 进行与运算
mask[ m ][ n ] = False
a[ m ][ n ] 与 b[ m ][ n ] 不进行与运算,直接为 0