在 Numpy 中结合广播和布尔数组索引进行图像屏蔽
Combining broadcast and boolean array indexing in Numpy for image masking
我正在处理图像 processing/building 问题。我有一个较小的图像,我想将其放入一个较大的图像中。正常情况下,图像表示为 3d 数组。这适用于以下代码(element_pixels
和 image_pixels
都是 3d ndarrays,深度为 3 表示 RGB,element_pixels
在其他维度上等于或小于 image_pixels
) :
element_pixels = element.get_pixels()
image_pixels[element.position[0]:element.position[0]+element.height, element.position[1]:element.position[1]+element.width, :] = element_pixels
但是我想将元素中的黑色像素视为透明。执行此操作的最简单方法似乎是屏蔽元素,因此我不修改 image_pixels,其中 element_pixel 为黑色。我尝试了以下方法,但我陷入了困境:
element_pixels = element.get_pixels()
b = np.all(element_pixels == [0, 0, 0], axis=-1)
black_pixels_mask = np.dstack([b,b,b])
image_pixels[element.position[0]:element.position[0]+element.height, element.position[1]:element.position[1]+element.width, :][black_pixels_mask] = element_pixels
这看起来可以正确生成遮罩,但我不知道如何使用它。我收到以下错误:
image_pixels[element.position[0]:element.position[0]+element.height, element.position[1]:element.position[1]+element.width, :][black_pixels_mask] = element_pixels
TypeError: NumPy boolean array indexing assignment requires a 0 or 1-dimensional input, input has 3 dimensions
如果我用一个常量替换最后的 = element_pixels
,则掩蔽类工作(即无异常运行),但我正在努力将其推断为解决方案。
尺寸的额外细节
element_pixels.shape=(40, 40,3)
image_pixels.shape=(100, 100,3)
image_pixels[element.position[0]:element.position[0]+element.height, element.position[1]:element.position[1]+element.width, :].shape = (40,40,3)
2d 中的 MRE
这捕获了我在没有额外维度的复杂性的情况下尝试做的事情。
import numpy as np
bg = np.ones((10,10))*0.5
img = np.concatenate([np.zeros((5,1)),np.ones((5,1))], axis=1)
mask = img == 0
# copy the *non-zero* pixel values of img to a particular location in bg
bg[5:10,5:7][mask] = img # this throws exception
print(bg)
好吧,您可以在 3 维阵列上使用 2 维蒙版。所以像这样的东西会将 img
的所有黑色像素替换为 background
.
的所有黑色像素
img = np.random.randint(0, 2, (10, 10, 3))
background = np.random.randint(0, 2, (10, 10, 3))
mask = np.all(img == [0,0,0], axis=2)
img[mask] = background[img]
我不确定我是否理解 image_pixels
中的内容,但我认为您可以做类似的事情。
经过一些实验后我发现(也许事后看来很明显)答案是你必须在两边都涂上面具。
所以参加我的 MRE:
import numpy as np
bg = np.ones((10,10))*0.5
img = np.concatenate([np.zeros((5,1)),np.ones((5,1))], axis=1)
mask = img > 0
bg[5:10,5:7][mask] = img[mask]
print(bg)
或者回到我原来的代码,唯一改变的行是:
image_pixels[element.position[0]:element.position[0]+element.height, element.position[1]:element.position[1]+element.width, :][~black_pixels_mask] = element_pixels[~black_pixels_mask]
我正在处理图像 processing/building 问题。我有一个较小的图像,我想将其放入一个较大的图像中。正常情况下,图像表示为 3d 数组。这适用于以下代码(element_pixels
和 image_pixels
都是 3d ndarrays,深度为 3 表示 RGB,element_pixels
在其他维度上等于或小于 image_pixels
) :
element_pixels = element.get_pixels()
image_pixels[element.position[0]:element.position[0]+element.height, element.position[1]:element.position[1]+element.width, :] = element_pixels
但是我想将元素中的黑色像素视为透明。执行此操作的最简单方法似乎是屏蔽元素,因此我不修改 image_pixels,其中 element_pixel 为黑色。我尝试了以下方法,但我陷入了困境:
element_pixels = element.get_pixels()
b = np.all(element_pixels == [0, 0, 0], axis=-1)
black_pixels_mask = np.dstack([b,b,b])
image_pixels[element.position[0]:element.position[0]+element.height, element.position[1]:element.position[1]+element.width, :][black_pixels_mask] = element_pixels
这看起来可以正确生成遮罩,但我不知道如何使用它。我收到以下错误:
image_pixels[element.position[0]:element.position[0]+element.height, element.position[1]:element.position[1]+element.width, :][black_pixels_mask] = element_pixels TypeError: NumPy boolean array indexing assignment requires a 0 or 1-dimensional input, input has 3 dimensions
如果我用一个常量替换最后的 = element_pixels
,则掩蔽类工作(即无异常运行),但我正在努力将其推断为解决方案。
尺寸的额外细节
element_pixels.shape=(40, 40,3)
image_pixels.shape=(100, 100,3)
image_pixels[element.position[0]:element.position[0]+element.height, element.position[1]:element.position[1]+element.width, :].shape = (40,40,3)
2d 中的 MRE 这捕获了我在没有额外维度的复杂性的情况下尝试做的事情。
import numpy as np
bg = np.ones((10,10))*0.5
img = np.concatenate([np.zeros((5,1)),np.ones((5,1))], axis=1)
mask = img == 0
# copy the *non-zero* pixel values of img to a particular location in bg
bg[5:10,5:7][mask] = img # this throws exception
print(bg)
好吧,您可以在 3 维阵列上使用 2 维蒙版。所以像这样的东西会将 img
的所有黑色像素替换为 background
.
img = np.random.randint(0, 2, (10, 10, 3))
background = np.random.randint(0, 2, (10, 10, 3))
mask = np.all(img == [0,0,0], axis=2)
img[mask] = background[img]
我不确定我是否理解 image_pixels
中的内容,但我认为您可以做类似的事情。
经过一些实验后我发现(也许事后看来很明显)答案是你必须在两边都涂上面具。
所以参加我的 MRE:
import numpy as np
bg = np.ones((10,10))*0.5
img = np.concatenate([np.zeros((5,1)),np.ones((5,1))], axis=1)
mask = img > 0
bg[5:10,5:7][mask] = img[mask]
print(bg)
或者回到我原来的代码,唯一改变的行是:
image_pixels[element.position[0]:element.position[0]+element.height, element.position[1]:element.position[1]+element.width, :][~black_pixels_mask] = element_pixels[~black_pixels_mask]