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 倍。
看看矢量化的力量!