0

I want to mask an array of pixels with an array of ones and zeros. I'm using Keras in graph mode, so only using operations that can be performed on tensors.

Most symbolic operators seem to work in graph mode, and there is a subset of numpy operations in keras.backend. But there is no support for no iterating or enumerating.

So for example I have:

    arr = [[(1,2,3),(2,3,4),(4,5,6)],[(5,6,7),(6,7,8),(7,8,9)]]
    mask = [[1, 0, 1],[0, 0, 1]]
    # and I want
    arr * mask == [[(1,2,3),(0,0,0),(4,5,6)],[(0,0,0),(0,0,0),(7,8,9)]]

The actual arrays are images, so much bigger than this example. Is there a reasonable way to mask points like this?

npjohns
  • 2,218
  • 1
  • 17
  • 16
  • 1
    I think masking is best done by multiplying. Could you extend (broadcast?) the mask to be the same shape as the image so you can do element-wise multiplication on them? This answer seems to do that https://stackoverflow.com/a/47289654/1318499 – user1318499 Oct 13 '19 at 03:31

1 Answers1

0

From the code your provide, one of easiest way to do is using broadcasting, like @user1318499 mentioned in the comments. Since mask is in shape of (2,3), and arr is in shape of (2,3,3), mask can be expanded one dim to do broadcast with arr.

import tensorflow as tf

arr = tf.reshape(tf.range(2*3*3), [2,3,3])
# array([[[ 0,  1,  2],
#         [ 3,  4,  5],
#         [ 6,  7,  8]],

#        [[ 9, 10, 11],
#         [12, 13, 14],
#         [15, 16, 17]]], dtype=int32)
mask = tf.constant([[1, 0, 1],[0, 0, 1]])
res = arr * tf.expand_dims(mask, axis=-1)
# array([[[ 0,  1,  2],
#         [ 0,  0,  0],
#         [ 6,  7,  8]],

#        [[ 0,  0,  0],
#         [ 0,  0,  0],
#         [15, 16, 17]]], dtype=int32)
zihaozhihao
  • 4,197
  • 2
  • 15
  • 25