Python 按位_和运算符在openCV中到底做了什么?
我不太明白在openCV中使用“bitwise_and”运算符时的作用。 我还想知道它的参数。 计算两个数组或一个 数组和标量 参数:Python 按位_和运算符在openCV中到底做了什么?,python,opencv,bit-manipulation,Python,Opencv,Bit Manipulation,我不太明白在openCV中使用“bitwise_and”运算符时的作用。 我还想知道它的参数。 计算两个数组或一个 数组和标量 参数: src1–第一个输入数组或标量 src2–第二个输入数组或标量 src–单输入阵列 值–标量值 dst–与输入阵列具有相同大小和类型的输出阵列 掩码–可选操作掩码,8位单通道阵列,指定要更改的输出阵列元素 以下是web上的一个示例: 一般用法是,您希望获得由另一个图像定义的图像子集,通常称为“掩码” 因此,假设您想要“抓取”8x8图像的左上象限。您可以形成一
- src1–第一个输入数组或标量
- src2–第二个输入数组或标量
- src–单输入阵列
- 值–标量值
- dst–与输入阵列具有相同大小和类型的输出阵列
- 掩码–可选操作掩码,8位单通道阵列,指定要更改的输出阵列元素
一般用法是,您希望获得由另一个图像定义的图像子集,通常称为“掩码” 因此,假设您想要“抓取”8x8图像的左上象限。您可以形成一个如下所示的遮罩:
1 1 1 1 0 0 0 0
1 1 1 1 0 0 0 0
1 1 1 1 0 0 0 0
1 1 1 1 0 0 0 0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
您可以使用Python生成上面的图像:
import numpy as np
mask = np.zeros(shape=(8,8), dtype=bool)
mask[0:4,0:4] = True
然后假设你有这样一个图像:
1 0 1 0 1 1 1 1
0 1 0 1 0 0 0 0
1 0 1 0 1 1 1 1
0 1 0 1 0 0 0 0
1 1 1 1 1 1 1 1
0 0 0 0 0 0 0 0
1 1 1 1 1 1 1 1
0 0 0 0 0 0 0 0
具体来说,假设上面的图像是美国国旗的简化表示:左上角是星星,其他地方都是横条。假设您想要形成上面的图像。您可以使用掩码、按位\u和按位\u或来帮助您
imageStars = np.ones(shape=(8,8), dtype=bool)
for r, row in enumerate(imageStars):
for c, col in enumerate(row):
if r % 2 != c % 2: # even row, odd column, or odd row, even column
imageStars[r,c] = False
imageBars = np.zeros(shape=(8,8), dtype=bool)
for r, row in enumerate(imageStars):
if r % 2 == 0:
imageBars[r,:] = True
现在你有了星星的图像:
1 0 1 0 1 0 1 0
0 1 0 1 0 1 0 1
1 0 1 0 1 0 1 0
0 1 0 1 0 1 0 1
1 0 1 0 1 0 1 0
0 1 0 1 0 1 0 1
1 0 1 0 1 0 1 0
0 1 0 1 0 1 0 1
还有一张酒吧的图片:
1 1 1 1 1 1 1 1
0 0 0 0 0 0 0 0
1 1 1 1 1 1 1 1
0 0 0 0 0 0 0 0
1 1 1 1 1 1 1 1
0 0 0 0 0 0 0 0
1 1 1 1 1 1 1 1
0 0 0 0 0 0 0 0
你想用一种特殊的方式把它们结合起来,形成国旗,星星在左上象限,横条在其他地方
imageStarsCropped = cv2.bitwise_and(imageStars, mask)
imageStarsCropped
将如下所示:
1 0 1 0 0 0 0 0
0 1 0 1 0 0 0 0
1 0 1 0 0 0 0 0
0 1 0 1 0 0 0 0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
0 0 0 0 1 1 1 1
0 0 0 0 1 1 1 1
0 0 0 0 1 1 1 1
0 0 0 0 1 1 1 1
1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1
0 0 0 0 1 1 1 1
0 0 0 0 0 0 0 0
0 0 0 0 1 1 1 1
0 0 0 0 0 0 0 0
1 1 1 1 1 1 1 1
0 0 0 0 0 0 0 0
1 1 1 1 1 1 1 1
0 0 0 0 0 0 0 0
1 0 1 0 1 1 1 1
0 1 0 1 0 0 0 0
1 0 1 0 1 1 1 1
0 1 0 1 0 0 0 0
1 1 1 1 1 1 1 1
0 0 0 0 0 0 0 0
1 1 1 1 1 1 1 1
0 0 0 0 0 0 0 0
你看到它是怎么形成的吗?按位_和
在imageStars
为1
且掩码
为1
的每个像素处返回1
;否则,它将返回0
现在让我们浏览一下图像栏。首先,让我们反转面具:
maskReversed = cv2.bitwise_not(mask)
bit-wise\u not
将1
转换为0
,将0
转换为1
。它“翻转位”maskReversed
的外观如下:
1 0 1 0 0 0 0 0
0 1 0 1 0 0 0 0
1 0 1 0 0 0 0 0
0 1 0 1 0 0 0 0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
0 0 0 0 1 1 1 1
0 0 0 0 1 1 1 1
0 0 0 0 1 1 1 1
0 0 0 0 1 1 1 1
1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1
0 0 0 0 1 1 1 1
0 0 0 0 0 0 0 0
0 0 0 0 1 1 1 1
0 0 0 0 0 0 0 0
1 1 1 1 1 1 1 1
0 0 0 0 0 0 0 0
1 1 1 1 1 1 1 1
0 0 0 0 0 0 0 0
1 0 1 0 1 1 1 1
0 1 0 1 0 0 0 0
1 0 1 0 1 1 1 1
0 1 0 1 0 0 0 0
1 1 1 1 1 1 1 1
0 0 0 0 0 0 0 0
1 1 1 1 1 1 1 1
0 0 0 0 0 0 0 0
现在,我们将使用maskReversed
来“抓取”我们想要的imagebar
部分
imageBarsCropped = cv2.bitwise_and(imageBars, maskReversed)
imageBarsCropped
的外观如下所示:
1 0 1 0 0 0 0 0
0 1 0 1 0 0 0 0
1 0 1 0 0 0 0 0
0 1 0 1 0 0 0 0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
0 0 0 0 1 1 1 1
0 0 0 0 1 1 1 1
0 0 0 0 1 1 1 1
0 0 0 0 1 1 1 1
1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1
0 0 0 0 1 1 1 1
0 0 0 0 0 0 0 0
0 0 0 0 1 1 1 1
0 0 0 0 0 0 0 0
1 1 1 1 1 1 1 1
0 0 0 0 0 0 0 0
1 1 1 1 1 1 1 1
0 0 0 0 0 0 0 0
1 0 1 0 1 1 1 1
0 1 0 1 0 0 0 0
1 0 1 0 1 1 1 1
0 1 0 1 0 0 0 0
1 1 1 1 1 1 1 1
0 0 0 0 0 0 0 0
1 1 1 1 1 1 1 1
0 0 0 0 0 0 0 0
现在,让我们结合两个“裁剪”的图像来形成旗帜
imageFlag = cv2.bitwise_or(imageStarsCropped, imageBarsCropped)
imageFlag
将如下所示:
1 0 1 0 0 0 0 0
0 1 0 1 0 0 0 0
1 0 1 0 0 0 0 0
0 1 0 1 0 0 0 0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
0 0 0 0 1 1 1 1
0 0 0 0 1 1 1 1
0 0 0 0 1 1 1 1
0 0 0 0 1 1 1 1
1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1
0 0 0 0 1 1 1 1
0 0 0 0 0 0 0 0
0 0 0 0 1 1 1 1
0 0 0 0 0 0 0 0
1 1 1 1 1 1 1 1
0 0 0 0 0 0 0 0
1 1 1 1 1 1 1 1
0 0 0 0 0 0 0 0
1 0 1 0 1 1 1 1
0 1 0 1 0 0 0 0
1 0 1 0 1 1 1 1
0 1 0 1 0 0 0 0
1 1 1 1 1 1 1 1
0 0 0 0 0 0 0 0
1 1 1 1 1 1 1 1
0 0 0 0 0 0 0 0
你明白为什么吗<无论何时imageStarsCropped[r,c]==1
或imagesbarscropped[r,c]==1,code>按位\u或返回1
我希望这能帮助你理解OpenCV中的逐位运算。这些属性与计算机进行算术运算的二进制数的位运算一一对应。由@mannyglover用美国国旗示例给出的答案非常棒!我还想快速补充一点,对于实际图像,任何0(沥青黑色)的像素值都是“假”。由于false&anything=false,值大于0的任何其他像素都将变为0
这意味着在应用逐位_和之后,遮罩的变黑像素将使原始图像中的各个像素变黑
以下是一个在OpenCV中完成的示例:
原始图像:
遮罩:
在应用result=cv2.bitwise_和(stack,stack,mask=mask)
之后:只是对上述答案的细化,而不是完整的答案。在现实生活中,图像数组的值从0到255,而不仅仅是0和1。在这种情况下,按位_或
所做的是将两个图像中的每个对应数字转换为其二进制形式,然后执行或或和或其他操作
例如:
考虑两个值233和180。这些数字中的bitwise_或为我们提供了253(使用cv2.bitwise_或(np.array([233]),np.array([180]))
。233和180的二进制等价物分别为11101001和10110100。对233和180的二进制等价物中的每个数字进行位运算或运算,得到11111101,与253相同。该数字是通过对233和180的二进制等价物中的每个数字进行或运算得到的(您可以验证)
and、not和xor的工作原理与或的工作原理类似,即对数字的位进行逻辑运算。运算符做什么?
,并对取自两个数组的元素执行逐位运算,src1
ndsrc2
。类似。逐位表示布尔运算在值的每一位之间进行,每一位
什么是掩码参数?
它实际上不是布尔掩码(布尔数组将被拒绝)。它是一种uint8
数组类型,其中值被检查为0或否。“掩码”的x、y形状与图像相同,但其元素是标量的,即对于uint8的图像100 x 50 x 3,掩码必须是uint8的数组100 x 50
如何使用口罩?
此遮罩确定是否对位置x,y处的一对像素执行操作。如果遮罩中位置x,y处的元素为0,则不执行任何操作,并且结果数组中的像素为0,0,0(黑色)。如果位于x,y位置的掩码元素不为空,则按位操作确定结果数组中的值
假设我们要提取一个圆内的像素,并使其他像素变白。这可以通过使用互补遮罩的逐位操作来完成:
将numpy导入为np
进口cv2
将matplotlib.pyplot作为plt导入
images='images/'
#读取图像330 x 379 x 3 uint8
img=cv2.imread(图像+sample.jpg)
#使用pyplot完成显示时重新排列通道
img[:,:,[0,1,2]=img[:,:,[2,1,0]]
#创建白色图像,3个通道330 x 379 x 3 uint8
w_3c=np.full_like(img,fill_值=(255255))
#定义磁盘元素
中心=(img.shape[1]//2,img.shape[0]//2)
半径=整数(最小(中心)*