Numba: A High Performance Python Compiler
使い方は簡単(ということにしておく)。pip install numba などでインストールしたあと
from numba import jit @jit(nopython=True) def function(): ~
以下のコードはLBPの基本機能を書いてみたのだが遅すぎて使えなかったもの。
細かくいじれば何割かは速くなるかもしれないが焼け石に水だ。
def lbp(img): h, w = img.shape res = np.zeros((h, w), np.uint8) order = [0, 1, 2, 5, 8, 7, 6, 3] weight = [128, 64, 32, 16, 8, 4, 2, 1] for i in range(1, h-1): for j in range(1, w-1): nb = (img[i-1:i+2, j-1:j+2] <= img[i,j]).ravel() val = 0 for (od, wt) in zip(order, weight): if nb[od]: val += wt res[i, j] = val return res
このコードにnumbaを導入したところ約19倍、十分使える速さになった。
from numba import jit import timeit @jit(nopython=True) def lbp(img): ~ 略 ~ img = cv2.imread("mandrill.png", 0) n = 3 result = timeit.repeat(lambda: lbp(img), number=n) print(min(result)/n)
さらにループの並列処理化(parallel=True、range -> numba.prange)及びlist -> ndarrayで38倍にまで上がった。
from numba import jit, prange @jit(nopython=True, parallel=True) def lbp(img): ~ 略 ~ order = np.array([0, 1, 2, 5, 8, 7, 6, 3]) weight = np.array([128, 64, 32, 16, 8, 4, 2, 1]) for i in prange(1, h-1): # 一番外側だけ for j in range(1, w-1): # 内側はそのまま ~ 略 ~
@jitなし
0.8785514999957135
@jitあり
0.045470933332884066
@jit + prange
0.023035266659765814