Dodaj wybraną przez indeks tablicę numpy do innej tablicy numpy z nakładającymi się indeksami

Nov 27 2020

Mam dwie tablice numpy imagei warped_imageoraz indeksów tablic ix,iy. Muszę dodać imagedo warped_imagetego, który image[i,j]jest dodawany do warped_image[iy[i,j],ix[i,j]]. Poniższy kod działa, jeśli pary (iy[i,j], ix[i,j])są unikalne dla wszystkich i,j. Ale jeśli nie są unikalne, tj. Gdy imagetrzeba dodać 2 elementy z do tego samego elementu w programie warped_image, tylko jeden z nich zostanie dodany. Jak mogę dodać oba elementy od imagedo tego samego elementu w warped_image?

Zauważ, że nie chcę używać żadnych forpętli. Chcę zachować to wektoryzację. Planuję w przyszłości przekonwertować kod na TensorFlow lub PyTorch, aby wykorzystać w tym celu możliwości GPU. To dlatego, że mam setki takich obrazów, a każdy z nich ma rozdzielczość full HD.

import numpy
image = numpy.array([[246,  50, 101], [116,   1, 113], [187, 110,  64]])
iy = numpy.array([[1, 0, 2], [1, 1, 0], [2, 0, 2]])
ix = numpy.array([[0, 2, 1], [1, 2, 0], [0, 1, 2]])
warped_image = numpy.zeros(shape=image.shape)
warped_image[iy, ix] += image

>> warped_image
Out[31]: 
array([[  113., 110.,  50.],
       [246., 116.,   1.],
       [187., 101.,  64.]])
   

W powyższym przypadku indeksy są unikalne, a zatem wynik jest zgodny z oczekiwaniami.

import numpy
image = numpy.array([[246,  50, 101], [116,   1, 113], [187, 110,  64]])
iy = numpy.array([[1, 0, 2], [1, 0, 2], [2, 2, 2]])
ix = numpy.array([[0, 2, 1], [1, 2, 0], [0, 1, 2]])
warped_image = numpy.zeros(shape=image.shape)
warped_image[iy, ix] += image

>> warped_image
Out[32]: 
array([[  0.,   0.,   1.],
       [246., 116.,   0.],
       [187., 110.,  64.]])
   

Oczekiwany wynik:

array([[  0.,   0.,   51.],
       [246., 116.,   0.],
       [300., 211.,  64.]])
       

W tym przypadku istnieją 3 pary indeksów, które nakładają się i dlatego zawodzą. Np. image[0,1]I image[1,1]należy dodać gt do, warped_image[0,2]aby uzyskać wartość 51. Jednak tylko jedna z nich ( image[1,1]) zostaje dodana, aby uzyskać wartość 1.

Kontekst :
próbuję wypaczyć obraz z widoku 1 do widoku 2. Obliczyłem, który piksel ma gdzie iść. W przypadku nakładania się pikseli, muszę wziąć średnią ważoną z nich. Więc muszę osiągnąć powyższe. Więcej szczegółów tutaj

Odpowiedzi

1 DaniMesejo Nov 27 2020 at 21:12

Użyj numpy.add.at :

import numpy
image = numpy.array([[246,  50, 101], [116,   1, 113], [187, 110,  64]])
iy = numpy.array([[1, 0, 2], [1, 0, 2], [2, 2, 2]])
ix = numpy.array([[0, 2, 1], [1, 2, 0], [0, 1, 2]])
warped_image = numpy.zeros(shape=image.shape)

np.add.at(warped_image, (iy, ix), image)

print(warped_image)

Wynik

[[  0.   0.  51.]
 [246. 116.   0.]
 [300. 211.  64.]]