微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

使用带条件的 numpy 迭代像素的更快方法?

如何解决使用带条件的 numpy 迭代像素的更快方法?

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

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。