Aggiungi un array numpy selezionato dall'indice a un altro array numpy con indici sovrapposti
Ho due array NumPy imageed warped_imagee indici array ix,iy. Ho bisogno di aggiungere imagea warped_imagetale che image[i,j]viene aggiunto a warped_image[iy[i,j],ix[i,j]]. Il codice seguente funziona se le coppie (iy[i,j], ix[i,j])sono uniche per tutti i,j. Ma quando non sono univoci, cioè quando 2 elementi da imagedevono essere aggiunti allo stesso elemento in warped_image, solo uno di essi viene aggiunto. Come posso aggiungere entrambi gli elementi da imageallo stesso elemento in warped_image?
Nota che non voglio usare alcun forloop. Voglio mantenerlo vettorializzato. Ho intenzione di convertire il codice in TensorFlow o PyTorch in futuro per utilizzare le funzionalità della GPU per questo. Questo perché ho centinaia di tali immagini e ogni immagine è di risoluzione 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.]])
Nel caso precedente, gli indici sono unici e quindi l'output è quello previsto.
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.]])
Uscita prevista:
array([[ 0., 0., 51.],
[246., 116., 0.],
[300., 211., 64.]])
In questo caso, ci sono 3 coppie di indici che si sovrappongono e quindi fallisce. Ad esempio, image[0,1]e image[1,1]dovrebbe essere aggiunto gt warped_image[0,2]per dare un valore 51. Tuttavia solo uno di essi ( image[1,1]) viene aggiunto per dare un valore 1.
Contesto :
sto cercando di deformare un'immagine da view1 a view2. Ho calcolato quale pixel deve andare dove. In caso di pixel sovrapposti, devo prendere una media ponderata di essi. Quindi, ho bisogno di ottenere quanto sopra. Maggiori dettagli qui
Risposte
Usa 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)
Produzione
[[ 0. 0. 51.]
[246. 116. 0.]
[300. 211. 64.]]