如何根据索引和值有效地更新np数组?

时间:2017-10-19 10:39:31

标签: python image numpy image-processing python-3.6

我有太阳的图像,我找到了中心和半径,现在我想要处理不同的像素,如果它们在磁盘内部或外部。理想的解决方案是插入处理函数的参数,以便从磁盘平滑过渡到背景。

以下是我现在正在做的事情:

for index,value in np.ndenumerate(sun_img):
    if distance.euclidean(index,center) > radius:
        sun_img[index] = processing_function(index,value)

像这样它可以工作,但计算图像需要永远。我相信有更有效的方法可以做到这一点。你会如何解决这个问题?

图像形状约为(1000,1000) Processing_function现在基本上没有做任何事情:值+ = 1

该函数应该类似于非线性“阶跃函数”,其中0.0值直到半径,1.0 5px之后。类似于:_______ /'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''斜率应该是半径的值。我想这样做是为了增强突起

1 个答案:

答案 0 :(得分:2)

这是一种利用NumPy broadcasting -

的矢量化方式
m,n = sun_img.shape  
I,J = np.ogrid[:m,:n]      
sq_dist = (I - center[0])**2 + (J - center[1])**2
valid_mask = sq_dist > radius**2

现在,对于processing_function,只需将1添加到IF-conditional定义的有效位置,即可 -

sun_img[valid_mask] += 1

如果您需要实现需要那些行,列索引的processing_function的自定义操作,请使用np.where来获取这些索引,然后遍历有效元素,如下所示 -

r,c = np.where(valid_mask)
for index in zip(r,c):
    sun_img[index] = processing_function(index,sun_img[r,c])

如果你有很多这样的有效位置,那么计算r,c可能会让事情变得缓慢。在这种情况下,直接使用mask,就像这样 -

for index,value in np.ndenumerate(sun_img):
    if valid_mask[index]:
        sun_img[index] = processing_function(index,value)

与原始代码相比,好处是我们在进入循环之前预先计算了条件值。最好的方法是对processing_function本身进行矢量化,使其适用于更大的数据块,但这取决于它的实现。