-1

我正在尝试将图像中的所有红色和蓝色像素更改为黑色以仅具有绿色像素(基于某些条件)。

为了做到这一点,我现在使用了多个 for 循环,这个过程虽然有效,但速度非常慢。

到目前为止我的代码 -

### Test image is my original RGB image
mat = np.asarray(testim)

for elemento in mat: 

    for pixel in element:

        if ((pixel[0] + pixel[2]) >= (2*pixel[1])): #Non-vegetation background changing to black according to the rule (R + B >= 2G)
          pixel[0] = 0
          pixel[1] = 0
          pixel[2] = 0
        
        elif pixel[1] > pixel[0] and pixel[1] > pixel[2] and pixel[1] > 25: # Treat these as green vegetation and do not change anything
          continue
        
        else: # Change background to black
          pixel[0] = 0
          pixel[1] = 0
          pixel[2] = 0
cv2_imshow(testim)
print(testim.shape)

有什么方法可以使用Numpy对其进行矢量化,而无需使用嵌套的 for 循环来使相同的过程更快地工作?我对 NumPy 操作有点陌生,对如何完成它感到困惑。感谢您的帮助!

例如:我的输入图像 - [1]:https ://i.stack.imgur.com/zWGtA.jpg

我现在具有上述逻辑的输出图像 - [2]:https ://i.stack.imgur.com/VkmLC.jpg

我希望使用更快的代码获得相同的输出,最好使用 NumPy 而不是我目前拥有的嵌套 for 循环

4

3 回答 3

2

我将图像数组拆分为三个数组(r、g、b)以使规则更直观。使用这种格式添加任何新的应该很容易!

r, g, b = mat[:,:,0], mat[:,:,1], mat[:,:,2]
rule_1 = (r + b > 2 * g)
rule_2 = ~((g > r) & (g > b) & (g > 25))
mat[rule_1 | rule_2] = 0
于 2021-06-23T12:35:31.540 回答
1

您应该能够使用 访问您的红色矩阵mat[:,:,0],并且使用绿色和蓝色访问您的红色矩阵。

你的绿色像素掩码是:

mask = (mat[:,:,1]>mat[:,:,0]) & (mat[:,:,1]>mat[:,:,2]) & (mat[:,:,1]>25)

您正在执行逐元素比较和逐元素 AND 以将比较组合到布尔 2D 矩阵中。

然后,您可以通过执行以下操作将其他像素归零:

# Repeat mask along the three channels
mask = np.repeat(mask[:,:,np.newaxis], 3, axis=2)

# Zero non-green elements
mat[~mask] = 0
于 2021-06-23T12:13:46.390 回答
1

从您的代码中,您不会更改值

pixel[1] > pixel[0] and pixel[1] > pixel[2] and pixel[1] > 25

所以我们可以形成这个条件的布尔数组,并将其逆索引到数组中,并将这些位置设置为 0:

# since used more than once, assign to a variable
green = mat[:, :, 1]

# your "elif" condition
not_change_condition = (green > mat[:, :, 0]) & (green > mat[:, :, 2]) & (green > 25)

# index with its inverse and change
mat[~not_change_condition] = 0
于 2021-06-23T12:14:06.567 回答