bitwise_and运算符在openCV中的具体作用是什么?

mfuanj7w  于 2023-02-23  发布在  其他
关注(0)|答案(7)|浏览(183)

我不太明白“bitwise_and”操作符在openCV中的作用。我还想知道它的参数。

62lalag4

62lalag41#

一般的用法是,您想要获取由另一个图像定义的图像的子集,通常称为“遮罩”。
假设你想“抓取”一张8x8图像的左上角,你可以形成一个如下所示的遮罩:
你可以用Python生成上面的图像:

import numpy as np

mask = np.zeros(shape=(8,8), dtype=bool)
mask[0:4,0:4] = True

假设你有这样一个图像:
具体来说,假设上面的图像是美国国旗的简化表示:左上角的星星,其他地方的条形。2假设你想形成上面的图像。3你可以使用掩码,bitwise_and和bitwise_or来帮助你。

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

现在你有了一幅恒星的图像:
以及条形图像:
你想用一种特殊的方式把它们组合起来,形成一面旗帜,左上角的星星和其他地方的横条。

imageStarsCropped = cv2.bitwise_and(imageStars, mask)

imageStarsCropped将类似于:
你知道它是怎么形成的吗?bitwise_and在每个像素返回1,其中imageStars1,而mask1;否则返回0
现在我们得到imageBarsCropped。首先,我们反转掩码:

maskReversed = cv2.bitwise_not(mask)

bitwise_not1转换为0,将0转换为1。它“翻转了位”。maskReversed看起来如下所示:

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

现在,我们将使用maskReversed“抓取”imageBars中我们想要的部分。

imageBarsCropped = cv2.bitwise_and(imageBars, maskReversed)

imageBarsCropped将类似于:

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

现在,让我们把这两张“裁剪”过的图片组合成旗帜!

imageFlag = cv2.bitwise_or(imageStarsCropped, imageBarsCropped)

imageFlag将类似于:
你知道为什么吗?每当imageStarsCropped[r,c]==1imageBarsCropped[r,c]==1时,bitwise_or返回1
我希望这能帮助你理解OpenCV中的位运算。这些属性与计算机进行算术运算时对二进制数的位运算一一对应。

ttvkxqim

ttvkxqim2#

操作员做什么?

bitwise_and,bitwise_or和bitwise_xor对两个数组src1src2中的元素执行按位运算。bitwise_not与之类似。按位意味着在值的每一位之间执行布尔运算,逐位执行。

什么是掩码参数?

它实际上不是一个布尔掩码(布尔数组将被拒绝)。它是一个uint8数组类型,检查值是否为0。“mask”具有与图像相同的x,y形状,但其元素是标量,即对于uint8的100 x 50 x 3图像,掩码必须是uint8的100 x 50数组。

如何使用面罩?

此掩码确定是否对位置x,y处的像素对执行运算。如果掩码中位置x,y处的元素为0,则不执行运算,结果数组中的像素为0,0,0(黑色)。如果位置x,y处的掩码元素不为空,则按位运算确定结果数组中的值。
假设我们想要提取一个圆内的像素并使其他像素为白色,这可以通过使用互补掩码进行逐位运算来实现:

import numpy as np
import cv2
import matplotlib.pyplot as plt

images = 'images/'

# Read image 330 x 379 x 3 uint8
img = cv2.imread(images + 'sample.jpg')

# Reorder channels as display is done with pyplot
img[:,:,[0,1,2]] = img[:,:,[2,1,0]]

# Create white image, 3 channels 330 x 379 x 3 uint8
w_3c = np.full_like(img, fill_value=(255,255,255))

# Define disk elements
center = (img.shape[1]//2, img.shape[0]//2)
radius = int(min(center) * .9)

# Create white disk, 3 channels 330 x 379 x 3 uint8
# and single channel 330 x 379 uint8
d_3c = np.zeros_like (img[:,:], dtype='uint8')
cv2.circle(d_3c, center, radius, [255]*3, thickness=cv2.FILLED)
d_1c = d_3c[:,:,0]

# Extract pixels disk using white disk single channel
masked = cv2.bitwise_and(img, w_3c, mask=d_1c)

# Add white background
d_3c_i = ~d_3c
final = cv2.bitwise_or(img, d_3c_i)

# Prepare to plot
to_plot = [[(img,'img'),
            (w_3c,'w_3c')],
           [(d_3c,'d_3c'),
            (d_1c,'d_1c'),
            (d_3c_i,'d_3c_i')],
           [(masked,'img & w_3c mask d_1c'),
            (final,'img | d_3c_i)')]]
r = len(to_plot)
c = max([len(l) for l in to_plot])

# Show everthing
fig,ax = plt.subplots(r,c, tight_layout=True)
for i in range(r):
    for j in range(c):
        axij = ax[i,j]
        if j < len(to_plot[i]):
            dims = to_plot[i][j][0].ndim
            if dims <= 3:
                axij.imshow(to_plot[i][j][0], cmap='gray')
            else:
                axij.imshow(to_plot[i][j][0])
            axij.set_title(to_plot[i][j][1])
            axij.set_xticks([])
            axij.set_yticks([])
        else:
            axij.set_axis_off()

plt.ioff()
plt.show()

代码可能可以改进。

wz3gfoph

wz3gfoph3#

只是对上述答案的详细说明,而不是完整的答案。在现实生活中,图像数组的值从0到255,而不仅仅是0和1。bitwise_or在这种情况下所做的是将两个图像中的每个对应数字转换为二进制形式,然后执行或其他操作。
示例:
考虑两个值233和180。这些数字的bitwise_or为253(使用cv2.bitwise_or(np.array([233]), np.array([180]))。233和180的二进制等效值为11101001和10110100。执行bitwise_or得到1111101,与253相同。此数字是通过执行获得的对于233和180的二进制等效值中的每个数字(您可以验证)

bin(233) #0b in the output just means it is a binary number
0b11101001

bin(180)
0b10110100

bin(253)
0b11111101

cv2.bitwise_or(np.array([233]), np.array([180]))
array([[253]], dtype=int32)
    • AND、NOT和XOR通过对数字的位进行逻辑运算,其工作方式与OR**类似。
wn9m85ua

wn9m85ua4#

@mannyglover对美国国旗的回答非常棒!我还要快速补充一点,对于实际图像,任何像素值为0(漆黑)的像素都是"假"的。因为false & anything = false,任何其他像素值大于0的像素都将变为0。
这意味着在应用bitwise_and之后,掩模的漆黑像素将使原始图像中的相应像素变为漆黑。
下面是一个在OpenCV中完成的示例:
原始图像:stack.jpg
掩码:mask.jpg
应用result = cv2.bitwise_and(stack, stack, mask=mask)后:result.jpg

uklbhaso

uklbhaso5#

对于正在寻找关于bitwise_or的简单解释的用户
假设我们要编写cv2.bitwise_or,我们必须:
1.仅在mask为非零的位置执行src1数组与src2数组的按位OR
因此,假设掩码为100x100形状,仅mak1 = 1,其他值均为0。此外,src1为600x600x3数组,所有值均为255,src2与src1相同。
因此,在cv2.bitwise_or操作之后,我们得到一个形状为600x600x3的输出数组,其中output1 = 255(因为这是我们艾德src1和src2进行逐位OR运算的唯一位置),并且输出数组的其余位置将为0。

dhxwm5r4

dhxwm5r46#

这些操作可用于选择性地修改或提取图像的特定区域。有时提取同类区域。它是选择、修改和分析图像特定区域的工作。

3npbholx

3npbholx7#

    • 按位与**

计算两个数组或一个数组和一个标量的按元素的按位合取。
参数:

  • src1-第一个输入数组或标量。
  • src2-第二个输入数组或标量。
  • src-单输入数组。
  • value-标量值。
  • dst-与输入数组具有相同大小和类型的输出数组。
  • mask-可选操作掩码,8位单通道数组,指定要更改的输出数组元素。

下面是一个在网上找到的例子:http://docs.opencv.org/trunk/d0/d86/tutorial_py_image_arithmetics.html

相关问题