Python では、ネストされたループは常に低速です。各ピクセルを反復処理するため、多くの時間がかかります。
ベクトル化された操作、つまり配列全体で操作を実行し、基礎となる C ルーチンにループを実行させる方が常に高速です。
私はcolormath
よく知らないので、このライブラリに対応するコードを提供することはできません (存在するかどうかもわかりません) scikit-image
。
def mask2(rgb, threshold=80, color=[255,20,147]):
res = rgb.copy()
lab = skimage.color.rgb2lab(rgb)
mask = lab[:,:,0] > threshold
res[mask] = np.array(color).reshape(1,-1).repeat(mask.sum(),axis=0)
return res
画像全体を LAB 空間に変換し、マスク (L がしきい値を超える) を決定し、これらのピクセルを新しい色に設定します。このメソッドは、メソッドとはわずかに異なる結果を生成します (おそらく変換の実装が異なるため) が、ニーズを満たす可能性があります。
mask1
以下は、メソッド ( ) とパフォーマンス測定値を含む完全なスクリプトです。
from binascii import unhexlify
import zlib
from cStringIO import StringIO
import skimage.io, skimage.color
from colormath.color_objects import RGBColor
import numpy as np
def mask1(img, treshold=80, color=[255,20,147]):
res=img.copy()
for x in range(img.shape[0]):
for y in range(img.shape[1]):
RGBimg=RGBColor(img[x,y,0],img[x,y,1],img[x,y,2])
LABimg=RGBimg.convert_to('lab', debug=False)
if (LABimg.lab_l > treshold):
res[x,y,:]=color
else:
res[x,y,:]=img[x,y,:]
return res
def mask2(rgb, threshold=80, color=[255,20,147]):
res = rgb.copy()
lab = skimage.color.rgb2lab(rgb)
mask = lab[:,:,0] > threshold
res[mask] = np.array(color).reshape(1,-1).repeat(mask.sum(),axis=0)
return res
sdata = "789C9D953D56C52010856363696D49E90AAC73ECDD4396C25228B210CE711B2CC2CAC622CECC9D0C0321313A27E411123EEEFCC07B7BFF7A9CC45EA9BD507BD6F620F769CAF4FEE3096DB76DDACEAEE9865D4CF79C6DAB34F46D441F7F23F88F6F728E6AD794724EDD5CBB9B790EF53FBF1595D9524C517E93CDEA3A433D984E83440327B318B633BF867A4C12734A5654CE26F24F29AB28704A067685363C665B0582D30ADF0F39A2717F3979C9412A6108A1D731C6992C04BD96252ECB9A2AC4A60F2B07904AA8166C84B51545D172C3C8D02B4CA3D51D841F7584B5CD2E17E2698A5DDE991302AD6240189666558242122D68F1C0F19F99475104D0F7C6216D5A6665AFAED62F8A27730A57E3BC4858669D25716B387BA04E39B41059BCC7E99CEAF4B05F971C75AAB0181AE938111CA9DB9A71C9B5443EA000D4231183A4F8ECEF79E7E5B40E2DEF647BDEA9AB6250EA59F70B6AC90E9FAABFB7D040E43C010107D4F1086A4ADA6D8DA66C8AEDD9C10E3514196A0F060220B59825C843883F5D71A67586809FEDF17FFCD75C4CFC012B43550B"
fh = StringIO(zlib.decompress(unhexlify(sdata)))
rgb = skimage.io.imread(fh)
res1 = mask1(rgb)
res2 = mask2(rgb)
import timeit
t1 = timeit.timeit("mask1(rgb)", setup="from __main__ import rgb, mask1", number=100)
t2 = timeit.timeit("mask2(rgb)", setup="from __main__ import rgb, mask2", number=100)
print t1, t2, t1/t2
このコードに画像を埋め込みましたが、コードの一部はそれをデコードするためだけのものです。
このスクリプトの出力は
4.43572092984 0.0531735152348 83.4197421453
つまり、私の方法はあなたの方法の80倍高速です。より大きな画像 (これは 24 x 24 ピクセルしかありません) の場合、違いはさらに大きく、120 倍の速さになります。
ベクトル化の力を見よ!