我正在嘗試使用 numba加速我對
uj5u.com熱心網友回復:
首先,不能從 Numba nopython jitted 函式(又名 njit 函式)呼叫純 Python 函式。這是因為 Numba 需要在編譯時跟蹤型別以生成高效的二進制檔案。
此外,Numba 無法編譯該運算式,pixel[:, np.newaxis].T因為np.newaxis它似乎尚不受支持(可能是因為np.newaxisis None)。您可以使用pixel.reshape(3, -1).T代替。
請注意,您應該注意型別,因為a - b在兩個變數都是型別時執行會np.uint8導致可能的溢位(例如0 - 1 == 255,甚至更令人驚訝的是:0 - 256 = 65280whenb是文字整數和a型別np.uint8)。請注意,該陣列是就地計算的,并且像素是在之前寫入的
盡管 Numba 做得很好,但生成的代碼效率不會很高。您可以使用回圈自己迭代顏色以找到最小索引。這要好一些,因為它不會生成很多小的臨時陣列。您還可以指定型別,以便 Numba 提前編譯函式。話雖如此。這也使代碼級別較低,因此更冗長/更難維護。
這是一個優化的實作:
@nb.njit('int32[::1](uint8[::1])')
def nb_findClosestColour(pixel):
colors = np.array([[255, 255, 255], [255, 0, 0], [0, 0, 255], [255, 255, 0], [0, 128, 0], [253, 134, 18]], dtype=np.int32)
r,g,b = pixel.astype(np.int32)
r2,g2,b2 = colors[0]
minDistance = np.abs(r-r2) np.abs(g-g2) np.abs(b-b2)
shortest = 0
for i in range(1, colors.shape[0]):
r2,g2,b2 = colors[i]
distance = np.abs(r-r2) np.abs(g-g2) np.abs(b-b2)
if distance < minDistance:
minDistance = distance
shortest = i
return colors[shortest]
@nb.njit('uint8[:,:,::1](uint8[:,:,::1])')
def nb_floydDither(img_array):
assert(img_array.shape[2] == 3)
height, width, _ = img_array.shape
for y in range(0, height-1):
for x in range(1, width-1):
old_pixel = img_array[y, x, :]
new_pixel = nb_findClosestColour(old_pixel)
img_array[y, x, :] = new_pixel
quant_error = new_pixel - old_pixel
img_array[y, x 1, :] = img_array[y, x 1, :] quant_error * 7/16
img_array[y 1, x-1, :] = img_array[y 1, x-1, :] quant_error * 3/16
img_array[y 1, x, :] = img_array[y 1, x, :] quant_error * 5/16
img_array[y 1, x 1, :] = img_array[y 1, x 1, :] quant_error * 1/16
return img_array
naive 版本快 14 倍,而最后一個版本快19 倍。
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/341078.html
