Agregue una matriz numérica seleccionada por índice a otra matriz numérica con índices superpuestos

Nov 27 2020

Tengo dos matrices numpy imagey warped_imagee índices de arrays ix,iy. Necesito agregar imagea lo warped_imageque image[i,j]se agrega a warped_image[iy[i,j],ix[i,j]]. El siguiente código funciona si los pares (iy[i,j], ix[i,j])son únicos para todos i,j. Pero cuando no son únicos, es decir, cuando es imagenecesario agregar 2 elementos al mismo elemento warped_image, solo se agrega uno de ellos. ¿Cómo puedo agregar ambos elementos del imagemismo elemento en warped_image?

Tenga en cuenta que no quiero utilizar ningún forbucle. Quiero mantener esto vectorizado. Estoy planeando convertir el código a TensorFlow o PyTorch en el futuro para usar las capacidades de GPU para esto. Eso es porque tengo cientos de imágenes de este tipo y cada imagen es de resolución 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.]])
   

Para el caso anterior, los índices son únicos y, por lo tanto, el resultado es el esperado.

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

Rendimiento esperado:

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

En este caso, hay 3 pares de índices que se superponen y, por lo tanto, fallan. Por ejemplo, image[0,1]y image[1,1]debería agregarse gt warped_image[0,2]para dar un valor de 51. Sin embargo, solo uno de ellos ( image[1,1]) se agrega para dar un valor de 1.

Contexto :
estoy intentando deformar una imagen de view1 a view2. He calculado qué píxel tiene que ir a dónde. En caso de píxeles superpuestos, necesito tomar un promedio ponderado de ellos. Entonces, necesito lograr lo anterior. Más detalles aquí

Respuestas

1 DaniMesejo Nov 27 2020 at 21:12

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

Salida

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