使用数组进行 Numpy 过滤

Rar*_*ima 0 python arrays numpy image-processing slice

我知道以前已经有人问过这个问题,但似乎没有任何适合我的特定用例的内容。

我有一个 numpy 数组obs,它表示彩色图像并具有 shape (252, 288, 3)

我想将每个非纯黑色的像素转换为纯白色。

我尝试过obs[obs != [0, 0, 0]] = [255, 255, 255]但它给出了以下例外:

ValueError: NumPy boolean array indexing assignment cannot assign 3 input values to the 807 output values where the mask is true

结果与 相同obs[obs[:, :] != [0, 0, 0]] = [255, 255, 255](obs[:, :] != [0, 0, 0]).shape另外,(252, 288, 3)我不明白为什么它不简单(252, 288)(布尔矩阵)。

我考虑过使用,obs[obs != 0] = 255但这不会达到我想要的效果,因为纯绿色 ( [0, 255, 0]) 的像素将按组件方式进行处理,并且[0, 255, 0]在过滤后仍然会出现,而不是实际上是白色的 ( [255, 255, 255])。

为什么我到目前为止所尝试的方法不起作用,我应该如何解决?

Ste*_*tef 5

布尔索引obs[obs != [0, 0, 0]]返回一个一维数组,其中所有元素都obs满足给定条件。看下面的例子:

obs = np.array([
 [[88, 0,99],
  [ 0, 0, 0]],
 [[ 0, 0, 0],
  [88,77,66]]
])
Run Code Online (Sandbox Code Playgroud)

obs != [0, 0, 0]返回一个布尔数组:

array([[[ True, False,  True],
        [False, False, False]],
       [[False, False, False],
        [ True,  True,  True]]])
Run Code Online (Sandbox Code Playgroud)

然后返回一个一维数组,其中包含掩码为:obs[obs != [0, 0, 0]]的所有元素。Truearray([88, 99, 88, 77, 66])

所以你需要where测试是否有any颜色分量不等于0:

np.where(obs.any(axis=-1, keepdims=True), 255, obs)
Run Code Online (Sandbox Code Playgroud)

结果:

array([[[255, 255, 255],
        [  0,   0,   0]],
       [[  0,   0,   0],
        [255, 255, 255]]])
Run Code Online (Sandbox Code Playgroud)

请注意,您需要keepdims=True启用广播到 的原始形状obs。否则,您必须通过np.where(obs.any(-1)[...,np.newaxis], 255, obs)或 来添加丢失的维度np.where(np.atleast_3d(obs.any(-1)), 255, obs),这不太优雅。