此代码将颜色空间更改为LAB,并使用阈值查找图像的皮肤区域。但它的速度非常慢。我不知道如何让它更快?
from colormath.color_objects import *
def skinDetection(img, treshold=80, color=[255,20,147]):
print img.shape
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
答案 0 :(得分:4)
嵌套循环在Python中总是很慢。迭代每个Pixel,因此需要花费很多时间。
执行向量化操作总是更快,即,对整个数组执行操作,让底层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倍。
答案 1 :(得分:0)
我建议您按照一个简单的流程来优化您的代码:
1.添加一些性能指标。您必须了解代码的哪一部分在大多数时间内都在使用
2.通过更多表现来更新这些功能
3.衡量绩效改进