Как быстро суммировать диапазон индексов в нескольких массивах в Python? - PullRequest
0 голосов
/ 01 мая 2020

Я пытаюсь восстановить HDR-изображение, используя уравнение, в котором я должен суммировать значения j (0-15) в числителе и знаменателе для каждого значения i. Есть ли более быстрый способ сделать это? Использование, возможно, 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

Ответы [ 2 ]

1 голос
/ 01 мая 2020

Вероятно, лучший способ сделать это - использовать 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
0 голосов
/ 01 мая 2020

@ Диллман опередил меня. Может быть, вы все еще можете использовать ниже, как это построить. Мне нравится думать пошагово.

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]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...