如何有条件地修改numpy多维数组的每个元素?

时间:2019-08-16 07:36:39

标签: python numpy

我使用opencv将图像转换为灰度numpy数组:

im_g=cv2.imread("smallgray.png",0)
print(im_g)

[[187 158 104 121 143]
 [198 125 255 255 147]
 [209 134 255  97 182]]

我想使那些大于200的值使图像变暗,例如255白色和0黑色。如果这样做,我将得到正确的结果:

im_g[im_g>200] = 150
print(im_g)

[[187 158 104 121 143]
 [198 125 150 150 147]
 [150 134 150  97 182]]

但是我的问题是,如果我不想使用常量(例如示例中的150),而是对当前元素执行一些计算,那我该如何引用该元素呢?

预先感谢

4 个答案:

答案 0 :(得分:1)

您可以使用where轻松地将操作向量化:

im_g = np.where(im_g < 150, im_g, np.random.randint(1, 40, size=im_g.shape))

答案 1 :(得分:0)

您可以使用列表理解来遍历列表列表,并使用if和else语句。例如

t=[[187, 158, 104, 121, 143],
 [198, 125, 255, 255, 147],
 [209, 134, 255,  97, 182]]

new=[[x*2-50 if x>190 else x for x in y] for y in t]

返回此

[[187, 158, 104, 121, 143],
 [3910, 125, 5050, 5050, 147],
 [4130, 134, 5050, 97, 182]]

这是您要找的吗?您可能可以将任何函数添加到列表推导中,以获得所需的确切条件

答案 2 :(得分:0)

假设您要在其上使用某些功能

def some_func(x):
    return x/10.

将数组转换为numpy数组:

import numpy as np
im_g = np.asarray(im_g)

并使用

im_g[im_g>200] = some_func(im_g[im_g>200])

答案 3 :(得分:0)

我最终使用了文档中所述的vectorize函数以及lambda函数(感谢@hilberts_drinking_problem指出了正确的方向)。如果将随机函数替换为自定义函数,则可以获得所需的功能,我只想留下一个模板以供将来参考:

=================
import random
import cv2
import numpy as np

#loading image as a numpy array(grayscale)
im_g=cv2.imread("smallgray.png",0)
print(im_g)    

=================

[[187 158 104 121 143]
 [198 125 255 255 147]
 [209 134 255  97 182]]

=================

#applying function conditionally to each element
index = lambda x: x if x < 150 else random.randint(1,40)
vfunc = np.vectorize(index)
vectorized_im=vfunc(im_g)
print(vectorized_im)  
cv2.imwrite("darkened.png",vectorized_im)

=================

array([[ 37,  38, 104, 121, 143],
       [ 34, 125,  40,   6, 147],
       [ 10, 134,   9,  97,  24]])