Har*_*uja 4 python opencv bit-manipulation
在openCV中使用时,我并不完全理解"bitwise_and"运算符的作用.我也想知道它的参数.
man*_*ver 28
一般用法是您想要获取由另一个图像定义的图像的子集,通常称为"掩码".
因此,假设您想要"抓住"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
Run Code Online (Sandbox Code Playgroud)
您可以使用Python生成上面的图像:
import numpy as np
mask = np.zeros(shape=(8,8), dtype=bool)
mask[0:4,0:4] = True
Run Code Online (Sandbox Code Playgroud)
然后假设你有一个像这样的图像:
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
Run Code Online (Sandbox Code Playgroud)
具体来说,想象一下上面的图像是美国国旗的简化表示:左上角的星星,其他地方的星星.假设您想要形成上面的图像.您可以使用掩码,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
Run Code Online (Sandbox Code Playgroud)
现在你有一个星星的形象:
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
Run Code Online (Sandbox Code Playgroud)
和酒吧的形象:
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
Run Code Online (Sandbox Code Playgroud)
并且你想以特定的方式组合它们,形成旗帜,左上象限中的星星和其他地方的条形.
imageStarsCropped = cv2.bitwise_and(imageStars, mask)
Run Code Online (Sandbox Code Playgroud)
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
Run Code Online (Sandbox Code Playgroud)
你看到它是如何形成的吗?该bitwise_and回报率1在每个像素地方imageStars是1和mask是1; 否则,它返回0.
现在让我们来imageBarsCropped.首先,让我们颠倒面具:
maskReversed = cv2.bitwise_not(mask)
Run Code Online (Sandbox Code Playgroud)
bitwise_not把它变成1's 0'和0's 1' 变成's'.它"翻转了一下". 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
Run Code Online (Sandbox Code Playgroud)
现在,我们将用maskReversed"抓住" imageBars我们想要的部分.
imageBarsCropped = cv2.bitwise_and(imageBars, maskReversed)
Run Code Online (Sandbox Code Playgroud)
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
Run Code Online (Sandbox Code Playgroud)
现在,让我们将两个"裁剪"的图像组合起来形成旗帜!
imageFlag = cv2.bitwise_or(imageStarsCropped, imageBarsCropped)
Run Code Online (Sandbox Code Playgroud)
imageFlag 看起来像:
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
Run Code Online (Sandbox Code Playgroud)
你明白为什么吗? bitwise_or返回1时imageStarsCropped[r,c]==1OR imageBarsCropped[r,c]==1.
好吧,我希望这有助于您理解OpenCV中的按位操作.这些属性与使用二进制数的按位运算一一对应,计算机可以进行算术运算.
运营商做什么的?
bitwise_and、bitwise_or和bitwise_xor对取自两个数组src1nd 的元素执行按位运算src2。bitwise_not类似。按位表示布尔运算是在值的每一位之间逐位完成的。
掩模参数是什么?
它实际上不是布尔掩码(布尔数组将被拒绝)。它是一种uint8数组类型,其中值被检查为 0 或非 0。“掩码”具有与图像相同的 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()
Run Code Online (Sandbox Code Playgroud)
代码可能还可以改进。
Sta*_*dis -2
\n\n\n计算两个数组或一个数组和一个标量的每个元素的按位合。
\n参数:
\n\n
\n- src1 \xe2\x80\x93 第一个输入数组或标量。
\n- src2 \xe2\x80\x93 第二个输入数组或标量。
\n- src \xe2\x80\x93 单输入数组。
\n- 值 \xe2\x80\x93 标量值。
\n- dst \xe2\x80\x93 输出数组,其大小和类型与输入数组相同。
\n- mask \xe2\x80\x93 可选操作掩码,8位单通道数组,指定要更改的输出数组的元素。
\n
这是在网上找到的示例:\n http://docs.opencv.org/trunk/d0/d86/tutorial_py_image_arithmetics.html
\n| 归档时间: |
|
| 查看次数: |
11761 次 |
| 最近记录: |