インデックスが選択されたnumpy配列を、インデックスが重複している別のnumpy配列に追加します

Nov 27 2020

私は2つのnumpyのアレイ持ちimagewarped_imageし、インデックス配列をix,iy。私は追加する必要imagewarped_imageなるようimage[i,j]に追加されますwarped_image[iy[i,j],ix[i,j]]。以下のコードは、ペア(iy[i,j], ix[i,j])がすべてに対して一意である場合に機能しますi,j。ただし、それらが一意でない場合、つまりimage、の同じ要素にから2つの要素を追加する必要がある場合warped_imageは、そのうちの1つだけが追加されます。imageの同じ要素に両方の要素を追加するにはどうすればよいwarped_imageですか?

forループは使いたくないことに注意してください。これをベクトル化しておきたい。将来的には、コードをTensorFlowまたはPyTorchに変換して、GPU機能を使用することを計画しています。それは、私にはそのような画像が何百もあり、各画像はフル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.]])
   

上記の場合、インデックスは一意であるため、出力は期待どおりです。

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

期待される出力:

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

この場合、重複する3組のインデックスがあるため、失敗します。例えば、image[0,1]image[1,1]に加えGTべきであるwarped_image[0,2](値51をそれらの一方のみを与えるようにはimage[1,1])値1を与えるために追加されます。

コンテキスト
画像をview1からview2にワープしようとしています。どのピクセルをどこに行かなければならないかを計算しました。ピクセルが重なっている場合は、それらの加重平均を取る必要があります。だから、私は上記を達成する必要があります。詳細はこちら

回答

1 DaniMesejo Nov 27 2020 at 21:12

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)

出力

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