Ajouter un tableau numpy sélectionné par index à un autre tableau numpy avec des index qui se chevauchent

Nov 27 2020

J'ai deux tableaux de numpy imageet warped_imageet les tableaux d'indices ix,iy. Je dois ajouter imageà warped_imagece qui image[i,j]est ajouté warped_image[iy[i,j],ix[i,j]]. Le code ci-dessous fonctionne si les paires (iy[i,j], ix[i,j])sont uniques pour tous i,j. Mais lorsqu'ils ne sont pas uniques, c'est-à-dire lorsque 2 éléments de imagedoivent être ajoutés au même élément dans warped_image, un seul d'entre eux est ajouté. Comment puis-je ajouter les deux éléments de imageau même élément dans warped_image?

Notez que je ne veux utiliser aucune forboucle. Je veux garder cela vectorisé. Je prévois de convertir le code en TensorFlow ou PyTorch à l'avenir pour utiliser les capacités GPU pour cela. C'est parce que j'ai des centaines d'images de ce type et que chaque image a une résolution 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.]])
   

Dans le cas ci-dessus, les indices sont uniques et, par conséquent, la sortie est comme prévu.

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.]])
   

Production attendue:

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

Dans ce cas, il y a 3 paires d'indices qui se chevauchent et qui échouent donc. Par exemple, image[0,1]et image[1,1]devrait gt ajouté pour warped_image[0,2]donner une valeur 51. Cependant, un seul d'entre eux ( image[1,1]) est ajouté pour donner une valeur 1.

Contexte :
j'essaye de déformer une image de view1 à view2. J'ai calculé quel pixel doit aller où. En cas de chevauchement de pixels, je dois en prendre une moyenne pondérée. Donc, je dois réaliser ce qui précède. Plus de détails ici

Réponses

1 DaniMesejo Nov 27 2020 at 21:12

Utilisez 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)

Production

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