1 回答

TA貢獻1802條經驗 獲得超5個贊
您的訪問索引已切換。你應該做down[y,x,0]etc. not down[x,y,0]。但是,我懷疑您在此處訪問時不會遇到任何錯誤,因為圖像是方形的。此外,與完整的浮點精度相比,當您以有限的精度將三個數字加在一起時,您的值將會溢出。例如,添加200 + 100 + 50無符號 8 位整數將導致350 % 256 = 94. 在你的無限結果中可能發生的是,要么你有完全黑色的像素,因此歸一化導致除以 0 錯誤,或者三個值的總和溢出給你一個 0 值再次給你這個結果。
您可以做的是執行完整性檢查,以確保如果三個通道的總和不等于 0,則執行歸一化。此外,您還需要更改精度,以便它可以在求和后處理更高的值。
換句話說:
def normalized(down):
norm_img = np.zeros(down.shape, down.dtype)
width,height,channels=down.shape
for y in range(0,height):
for x in range(0,width):
sum=float(down[y,x,0])+float(down[y,x,1])+float(down[y,x,2]) # Change
if sum > 0: # Change
b=(down[y,x,0]/ sum)*255.0 # Change
g=(down[y,x,1]/ sum)*255.0
r=(down[y,x,2]/ sum)*255.0
norm_img[y,x,0]= b # Should cast downwards automatically
norm_img[y,x,1]= g
norm_img[y,x,2]= r
return norm_img
這當然是非常低效的,因為您在單個像素上循環并且沒有利用體現 NumPy 數組的矢量化。簡單的說,numpy.sum沿第三個維度求和,然后將每個通道除以相應的量:
def normalized(down):
sum_img = np.sum(down.astype(np.float), axis=2)
sum_img[sum_img == 0] = 1
return (255 * (down.astype(np.float) / sum_img[...,None])).astype(down.dtype)
第一行計算一個二維數組,其中每個位置沿通道維度求和,為您提供每個空間位置的 RGB 值之和。我還將類型提升為浮點數以在規范化時保持精度。接下來,第二行代碼的中間檢查確保沒有被零除的錯誤,所以任何為 0 的像素,我們將標記值設置為 1,以便除法結果為 0 值。之后,我們獲取輸入圖像并將每個相應的 RGB 像素除以相應空間位置的總和。請注意,我使用了廣播,以便將 2D 總和數組制作成具有單例第三通道的 3D 數組,以使廣播正常工作。最后,我乘以 255,就像您在之前的版本中所做的那樣。
為了更簡潔一點,您可以通過使用keepdims參數來進一步簡化此操作numpy.sum,以便在對第三維求和后維護單例維。這樣就避免了手動單例維度插入:
def normalized(down):
sum_img = np.sum(down.astype(np.float), axis=2, keepdims=True)
sum_img[sum_img == 0] = 1
return (255 * (down.astype(np.float) / sum_img)).astype(down.dtype)
添加回答
舉報