如何在Python中快速求和多个数组中的一系列索引?

2024-09-29 19:28:41 发布

您现在位置:Python中文网/ 问答频道 /正文

我试图用一个方程式来重建HDR图像,在这个方程式中,我必须对每个i值的分子和分母中的j值(0-15)求和。有没有更快的方法?使用np.sum

g是一个长度为255的一维数组,用于重新映射所有像素值

lEks是15幅图像的对数曝光时间

Z是一个大小为[95488,15]的数组,第一个维度是像素索引,第二个维度是图像编号

def genHDR(Z,g,lEks):

    Zi, Zj = Z.shape        #[95488, 15]
    HDRimage= np.zeros(Zi)

    for i in range(Zi):
        numerator   = 0
        denominator = 0

        for j in range(Zj):
            numerator   +=(Z[i,j])*(g[Z[i,j]] - lEks[j])
            denominator +=(Z[i,j])

        HDRimage[i] = numerator/denominator
    return HDRimage

Tags: in图像fornprange像素数组方程式
2条回答

@Dillman击败了我。也许你仍然可以使用下面的方法来构造它。我喜欢分步思考

import numpy as np

Z=  np.random.randint(low=0,high=256,size=(6,3))   # assume just 3 images with 6 pixels each
print(f' Z= {Z}')

lEks=np.random.rand(3)
print(f'lEks = {lEks}')

g0=np.arange(255)   #some example mapping; here from byte to half byte
g= g0//2        # // integer division


npxl,nimage=np.shape(Z)
print(f'npxl={npxl} nimage={nimage}')

# vectorize just one operation at first, easier to visualize
hdr=np.zeros(npxl)

for i in np.arange(npxl):
    #print(Z[i])
    denom=np.sum(Z[i])
    hdr[i]= np.sum(Z[i] *(g[Z[i]]- lEks))/denom 
    # Z[i] is just a vector of length 3, just like lEks

print(hdr)

# this would do it, but still be slower than necessary, as your remaining loop has many more elements that 
# the one we dealt with


# now vectorize the other coordinate (remove the remaining for-loop)
hdr=np.zeros(npxl)
hdr=  np.sum(Z *(g[Z]- lEks), axis=1)/ np.sum(Z,axis=1)   # which axis to sum over is critical
print(hdr)

#final code

def genHDR(Z, g, lEks):
    npxl,nimage=np.shape(Z)
    hdr=np.zeros(npxl)
    hdr=  np.sum(Z *(g[Z]- lEks), axis=1)/ np.sum(Z,axis=1) 
    return hdr


print(genHDR(Z,g,lEks))

输出:

 Z= [[199 101  67]
 [134  16 137]
 [219   5 135]
 [153  19  17]
 [238  41 120]
 [ 93  50 179]]
lEks = [0.57778608 0.18113957 0.85257974]
npxl=6 nimage=3
[72.94714613 63.50130665 91.04028102 62.58551969 90.46303414 65.97390417]
[72.94714613 63.50130665 91.04028102 62.58551969 90.46303414 65.97390417]
[72.94714613 63.50130665 91.04028102 62.58551969 90.46303414 65.97390417]

最好的方法可能是使用np.Array.sum(axis=1)。假设g(Z[i,j])调用是有效的。实际上,您甚至不需要任何循环:

import numpy as np

Z = np.random.randint(0,255,(10,15))
g=np.random.randint(0,10,(256))
lEks = np.random.rand((15))

def genHDR(Z,g,lEks):
    numerator = (Z*(g[Z]-lEks.view().reshape((1,)+ lEks.shape))).sum(axis=1)
    denominator = Z.sum(axis=1)
    HDRimage = numerator/denominator
    return HDRimage

相关问题 更多 >

    热门问题