我正在尝试将图像中的所有红色和蓝色像素更改为黑色,以便只有绿色像素(基于某些条件(。
为了做到这一点,我现在使用了多个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)
有没有什么方法可以在不使用嵌套for循环的情况下使用Numpy将其矢量化,以使相同的进程更快地工作?我对NumPy操作有点陌生,对如何完成它感到困惑。我很感激你的帮助!
例如:我的输入图像-[1]:https://i.stack.imgur.com/zWGtA.jpg
我现在拥有的输出图像具有上述逻辑-[2]:https://i.stack.imgur.com/VkmLC.jpg
我想要相同的输出和更快的代码,最好使用NumPy,而不是我目前拥有的嵌套for循环
我将图像数组拆分为三个数组(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
您应该能够使用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
根据您的代码,当
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