2017-10-19 86 views
1

我有一个太阳的图像,我发现中心和半径,现在我想处理像素不同,如果他们是在磁盘内部或外部。理想的解决方案将是插入处理函数的参数,以便顺利地从磁盘过渡到背景。如何根据索引和值有效更新np数组?

这是我现在在做什么:

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之后。例如:_______ /''''''''''''''乘以像素的值。斜率应该在半径的值上。我想,以增强突起

+0

我仍然必须编写函数,现在它正在执行value + = 1来查看会发生什么。这需要一个世纪。图像大约是(1k * 1k) – RobiNoob

+0

不,灰度,dtype np.float64 – RobiNoob

+0

'radius'和'center',那些标量是什么? – Divakar

回答

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那东东的自定义操作DS的行,列的索引,使用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,以便它可以处理更大的数据块,但这取决于它的实现。

+0

我现在正在吃午餐,所以我不能尝试它,但为什么你会认为这样更有效率?我的意思是np.where减少了for的像素数量,但数量级相同,并且以相同的方式访问像素 – RobiNoob

+0

@RobiNoob因为您正在执行'distance.euclidean(index,center )> radius:'在一个循环中,建议的方法以向量化的方式进行。再说一次,如果你的'processing_function'计算量比这个大得多,当然你可能看不到很大的好处。这就是为什么我在开始时询问是否可以共享'processing_function'的实现。 – Divakar

+0

好的,我回来了,我会试试这个。该函数应该是类似非线性的“阶跃函数”,其值为0.0,直到半径为1。0后5px。例如:_______ /''''''''''''''乘以像素的值。 斜率应该在半径的值上。我想这样做是为了增强突起 – RobiNoob