2017-10-19 87 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