Fügen Sie einem anderen numpy-Array mit überlappenden Indizes ein indexausgewähltes numpy-Array hinzu

Nov 27 2020

Ich habe zwei numpy Arrays imageund warped_imageund Indizes Arrays ix,iy. Ich muss zu solchen hinzufügen image, warped_imagedie image[i,j]hinzugefügt werden warped_image[iy[i,j],ix[i,j]]. Der folgende Code funktioniert, wenn die Paare (iy[i,j], ix[i,j])für alle eindeutig sind i,j. Wenn sie jedoch nicht eindeutig sind, dh wenn zwei Elemente von imagedemselben Element in hinzugefügt werden müssen warped_image, wird nur eines von ihnen hinzugefügt. Wie kann ich beide Elemente imagezu demselben Element hinzufügen warped_image?

Beachten Sie, dass ich keine forSchleifen verwenden möchte . Ich möchte dies vektorisiert halten. Ich plane, den Code in Zukunft in TensorFlow oder PyTorch zu konvertieren, um die GPU-Funktionen dafür zu nutzen. Das liegt daran, dass ich Hunderte solcher Bilder habe und jedes Bild eine Full-HD-Auflösung hat.

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

Für den obigen Fall sind die Indizes eindeutig und daher ist die Ausgabe wie erwartet.

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

Erwartete Ausgabe:

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

In diesem Fall gibt es 3 Indexpaare, die sich überlappen und daher fehlschlagen. ZB image[0,1]und image[1,1]sollte gt hinzugefügt werden, warped_image[0,2]um einen Wert 51 zu erhalten. Allerdings wird nur einer von ihnen ( image[1,1]) hinzugefügt, um einen Wert 1 zu ergeben.

Kontext :
Ich versuche, ein Bild von Ansicht1 nach Ansicht2 zu verzerren. Ich habe berechnet, welches Pixel wohin gehen muss. Bei überlappenden Pixeln muss ich einen gewichteten Durchschnitt davon nehmen. Also muss ich das oben genannte erreichen. Weitere Details hier

Antworten

1 DaniMesejo Nov 27 2020 at 21:12

Verwenden Sie 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)

Ausgabe

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