title: Converting Tensorflow Object Detection API model results into a mask tensor
body: <p><strong>The task:</strong></p>
  
  <p>I'm trying to integrate a model trained and exported via the Tensorflow Object Detection API into a larger graph that will convert the model results into a detection mask; essentially a float32 tensor of the same (height x width) dimensions as the input image, wherein each value reflects the model's confidence that the corresponding pixel lies within the bounding box of a detected object.  This is very similar to the output of a segmentation network, except the output I'm looking for isn't of dimension (height x width x num_classes), it is of dimension (height x width), as if there is only a single class being detected.  I would like to do this entirely within a Tensorflow graph.</p>
  
  <p><strong>How I'm trying to accomplish it:</strong> </p>
  
  <p>I'm trying to use tf.boolean_mask() and tf.foldl() to incrementally build the mask from the box bounds returned by the detection model.   Note that in this example the mask values are binary; to keep the question simple I took out the code that scales the results by the detection confidence.</p>
  
  <pre><code> def __init__(self, graph_protobuf, threshold=0.6):
      #Import code omitted...
      #Grab the model detection results:
      boxes = tf.squeeze(detection_graph.get_tensor_by_name('detection_boxes:0'), axis=0)
      scores = tf.squeeze(detection_graph.get_tensor_by_name('detection_scores:0'), axis=0)
      classes = tf.squeeze(detection_graph.get_tensor_by_name('detection_classes:0'), axis=0)
      num_detect = detection_graph.get_tensor_by_name('num_detections:0')
      #Only consider boxes above a provided threshold:
      over_threshold = tf.greater(scores, threshold)
      detections = tf.logical_and(over_threshold, tf.equal(classes, 1))
  
      #Debugging: Print out what the model result dimensions are.
      test = detection_graph.get_tensor_by_name('detection_scores:0')
      print("Shape of mask: {}  Shape of scores: {}   Shape of classes: {}  Raw score shape: {}".format(str(detections.shape), str(scores.shape), str(classes.shape), str(test.shape)))
      print("Boxes: {}".format(str(test)))
  
      #Remove under-threshold results:
      detection_boxes = tf.boolean_mask(boxes, detections)
      #Build the mask:
      self.result = tf.foldl(processBox, detection_boxes, initializer=tf.zeros([720,1280]))
  
   def processBox(self, res, box):
      res[box[0]:box[2],box[1]:box[3]].assign(tf.ones(((box[2]-box[0]),(box[3]-box[1]))))
  </code></pre>
  
  <p><strong>The problem:</strong></p>
  
  <p>I think Tensorflow is having trouble with the unknown number of boxes returned by the model.   Here is the result of trying to use this graph:</p>
  
  <pre><code> Shape of mask: &lt;unknown&gt;  Shape of scores: &lt;unknown&gt;   Shape of classes: &lt;unknown&gt;  Raw score shape: &lt;unknown&gt;
   Boxes: Tensor("detection_scores:0", dtype=float32)
  
   &lt;...uninteresting stack trace omitted...&gt;
  
   File "/home/username/.local/lib/python3.5/site-packages/tensorflow/python/ops/array_ops.py", line 1121, in boolean_mask
  "Number of mask dimensions must be specified, even if some dimensions"
  ValueError: Number of mask dimensions must be specified, even if some dimensions are None.  E.g. shape=[None] is ok, but shape=None is not.
  </code></pre>
  
  <p>Which is a complaint about tf.boolean_mask().   As you can see, at runtime I can't grab the model output dimensions at all.  tf.boolean_mask() works just fine with tf.constants as input, so this leads me to conclude that this approach may have some fundamental problems.</p>
  
  <p>Is there a way to make this approach work?  If not, what is the right way to build the mask result I'm looking for?</p>