2015-01-07 100 views
1

我有2個Numpy數組,我需要對它們執行一些基本的數學運算。
但由於最終numpy數組的類型(uint8)(名爲magnitude),我也無法將此操作的結果大於255。任何想法?除了通過遍歷數組...用兩個Numpy數組執行數學運算 - 限制數

# Notice that the data type is "np.uint8", also arrays are 2D 
magnitude = np.zeros((org_im_width,org_im_height), dtype=np.uint8) 

# "numpy_arr_1" and "numpy_arr_2" both of the same size & type as "magnitude" 

# In the following operation, I should limit the number to 255 
magnitude = ((np.int_(numpy_arr_1))**2 + (np.int_(numpy_arr_2))**2)**0.5 

# The following doesn't work obviously: 
# magnitude = min(255,((np.int_(numpy_arr_1))**2+(np.int_(numpy_arr_2))**2)**0.5) 

回答

3

首先,如果你在創建後分配magnitude = ...的,你被obtianed在操作,所以幅度不會再被替換UINT8初始UINT8數組。

無論如何,如果僅僅是在例如一個錯誤,執行你願意,你可以得到的操作clamp/clipnormalize值是什麼:

你可以找到np.clip這限制數組的值一個minmax值:

>>> magnitude = np.clip(operation, 0, 255) 

在哪裏操作你計算幅度。事實上,你可能想要的是:

>>> magnitude = np.clip(np.sqrt(a**2 + b**2), 0, 255).astype(np.uint8) 

ab分別是你的np.int_(numpy_arr_1)np.int_(numpy_arr_2),改名爲了提高可讀性。

此外,在你的情況下,所有值都爲正,則可以通過np.minimum代替np.clip

>>> magnitude = np.minimum(np.sqrt(a**2 + b**2), 255).astype(np.uint8) 

然而,這只是限制了矢量255(你想要的)的大小,但你將丟失更多數量的points大量的信息。如果某個點的數值是1000,則它將被限制到255,因此在你的最終數組1000 = 255中。幅度變化很大的兩個點最終會具有相同的幅度(在這種情況下爲1000和255)。

要避免這種情況,您可以將normalize(重新縮放)到[0, 255]。這意味着,如果在初始計算的幅度陣列處於所述範圍[0, 1000],把它轉換爲[0, 255]所以1000之前將255之後,但255之前現在將63(簡單的線性縮放比例)。

>>> tmp = np.sqrt(a**2 + b**2).astype(float) 
>>> magnitude = (tmp/tmp.max() * 255).astype(np.uint8) 

tmp/tmp.max()將重新調整的所有值以[0, 1]範圍(如果該數組是浮動),並且通過該陣列被再次reescaled到[0, 255]由255相乘。

如果您幅度的下限範圍不0,你可以說[200, 1000][0, 255]更好地代表了您的數據進行re-scale

>>> tmp = np.sqrt(a**2 + b**2).astype(float) 
>>> tmax, tmin = tmp.max(), tmp.min() 
>>> magnitude = ((tmp - tmin)/(tmax - tmin) * 255).astype(np.uint8) 
+0

1.爲什麼會選擇使用'np.sqrt'代替** 0.5'? 2.關於信息丟失 - 我瞭解 - 我的目標是,Numpy數組中的數據最終將成爲'uint8',而忽略信息丟失。 3。我**不得**執行線性縮放!它會改變其他值,這些值不會高於255. 我的目標是執行該數學運算,並確保只有**值超過255的值將被更改爲255.這是因爲我最後的Numpy數組應該包含其類型爲「uint8」的數據。 謝謝! – Dor

+0

'np.sqrt'和'** 0.5'做同樣的事,都是有效的。我只是更喜歡'np.sqrt',因爲它更具可讀性。由於我不知道你的手術的最終目標,我試圖展示所有可能的選擇。那麼'np.minimum'應該適合你。 –

+0

這是行不通的:如果'a'和'b'是dint'uint8',當你做'a ** 2 + b ** 2'時,任何超過'255'的結果都會溢出,只有LSB位將被保留,例如如果你有'a = np.array([15,17],dtype = np.uint8)',那麼'a ** 2'的值爲'array([225,33],dtype = uint8)',其中'33 = 17 * 17%256'。因此,除非原始數組被轉換,否則正確解釋的剪切不起作用。在執行這些操作之前,先將它們'浮動'dtype。 – Jaime