问题描述
def colorize(im,h,s,l_adjust):
result = Image.new('RGBA',im.size)
pixin = np.copy(im)
pixout = np.array(result)
>>>>>>>>>>>>>>>>> loop <<<<<<<<<<<<<<<<<
for y in range(pixout.shape[1]):
for x in range(pixout.shape[0]):
lum = currentRGB(pixin[x,y][0],pixin[x,y][1],y][2])
r,g,b = colorsys.hls_to_rgb(h,lum,s)
r,b = int(r * 255.99),int(g * 255.99),int(b * 255.99)
pixout[x,y] = (r,b,255)
>>>>>>>>>>>>>>>>>>>>> Loop end <<<<<<<<<<<
return result
试图从一帧输入视频中找到每个像素的 HSL 值,但它花费了大约 1.5 秒的时间,但希望将时间减少到至少 0.3 秒以内。在不使用这两个循环的情况下,有没有更快的方法来做到这一点?寻找类似 LUT(Look up table)/vectorize/something with NumPy 快捷方式来避免这两个循环。谢谢
或
第 2 部分 ->>
如果我将自定义 currentRGB() 分解为 for 循环,它看起来像:
def colorize(im,im.size)
pixin = np.copy(im)
pixout = np.array(result)
for y in range(pixout.shape[1]):
for x in range(pixout.shape[0]):
currentR,currentG,currentB = pixin[x,y][0]/255,y][1]/255,y][2]/255
#luminance
lum = (currentR * 0.2126) + (currentG * 0.7152) + (currentB * 0.0722)
if l_adjust > 0:
lum = lum * (1 - l_adjust)
lum = lum + (1.0 - (1.0 - l_adjust))
else:
lum = lum * (l_adjust + 1)
l = lum
r,l,255)
return pixout
解决方法
您可以使用 Numba 来大幅加快计算速度。这是实现:
import numba as nb
@nb.njit('float32(float32,float32,float32)')
def hue_to_rgb(p,q,t):
if t < 0: t += 1
if t > 1: t -= 1
if t < 1./6: return p + (q - p) * 6 * t
if t < 1./2: return q
if t < 2./3: return p + (q - p) * (2./3 - t) * 6
return p
@nb.njit('UniTuple(uint8,3)(float32,float32)')
def hls_to_rgb(h,l,s):
if s == 0:
# achromatic
r = g = b = l
else:
q = l * (1 + s) if l < 0.5 else l + s - l * s
p = 2 * l - q
r = hue_to_rgb(p,h + 1./3)
g = hue_to_rgb(p,h)
b = hue_to_rgb(p,h - 1./3)
return (int(r * 255.99),int(g * 255.99),int(b * 255.99))
@nb.njit('void(uint8[:,:,::1],uint8[:,float32)',parallel=True)
def colorize_numba(pixin,pixout,h,s,l_adjust):
for x in nb.prange(pixout.shape[0]):
for y in range(pixout.shape[1]):
currentR,currentG,currentB = pixin[x,y,0]/255,pixin[x,1]/255,2]/255
#luminance
lum = (currentR * 0.2126) + (currentG * 0.7152) + (currentB * 0.0722)
if l_adjust > 0:
lum = lum * (1 - l_adjust)
lum = lum + (1.0 - (1.0 - l_adjust))
else:
lum = lum * (l_adjust + 1)
l = lum
r,g,b = hls_to_rgb(h,s)
pixout[x,0] = r
pixout[x,1] = g
pixout[x,2] = b
pixout[x,3] = 255
def colorize(im,l_adjust):
result = Image.new('RGBA',im.size)
pixin = np.copy(im)
pixout = np.array(result)
colorize_numba(pixin,l_adjust)
return pixout
这种优化的并行实现比我的 6 核机器上的原始代码(800x600 图像)快约 2000 倍。 hls_to_rgb
实现来自 this post。请注意,@nb.njit
装饰器中的字符串不是必需的,但可以让 Numba 提前编译函数,而不是在第一次调用时编译。有关类型的更多信息,请阅读 Numba documentation。