class_docstr: Model using ResNet50 to predict single 3D oriented bounding box.
docstr: Adds the decoded predictions to the output dict.
  
  Args:
    predictions: The predictions of the model.
    inputs: Input dict to the model.
    outputs: Output dict of the model.
  
  Returns:
    The updated output dict.
docstr_tok: ["Adds","the","decoded","predictions","to","the","output","dict",".","Args",":","predictions",":","The","predictions","of","the","model",".","inputs",":","Input","dict","to","the","model",".","outputs",":","Output","dict","of","the","model",".","Returns",":","The","updated","output","dict","."]
code: def decode_predictions(predictions, inputs, outputs):
      """Adds the decoded predictions to the output dict.
  
      Args:
        predictions: The predictions of the model.
        inputs: Input dict to the model.
        outputs: Output dict of the model.
  
      Returns:
        The updated output dict.
      """
      predicted_center2d_offset = predictions[:, 0:2]
      predicted_size2d_offset = predictions[:, 2:4]
      predicted_camera_pose = predictions[
          :, 4:9
      ]  # 1d height, 2d rotation
      object_translation = predictions[:, 9:12]  # 3d translation
      object_rotation = predictions[
          :, 12:16
      ]  # 4d rotation (rotation matrix)
      object_size = predictions[:, 16:19]  # 3d size
  
      # Camera Pose
      outputs["camera_translation_z"] = predicted_camera_pose[:, 0]
      outputs["camera_translation"] = 0
      outputs["camera_rotation_cos_sin"] = predicted_camera_pose[:, 1:]
  
      # Compute the dot on the ground plane used as prior for 3d pose (batched)
      image_size = inputs["image_size"][
          0
      ]  # assuming it is the same size for all
      ray_2d = tf.cast(image_size, tf.float32) * [
          0.5,
          3.0 / 4.0,
          1 / image_size[-1],
      ]
      ray_2d = tf.reshape(ray_2d, [3, 1])
      k = inputs["k"]
      k_inv = tf.linalg.inv(k)
      rt = inputs["rt"]
      r = tf.gather(rt, [0, 1, 2], axis=2)
      t = tf.gather(rt, [3], axis=2)
      r_inv = tf.transpose(r, [0, 2, 1])
      t_inv = tf.matmul(r_inv, t) * -1
      ray = tf.matmul(r_inv, tf.matmul(k_inv, ray_2d))
      l = -t_inv[:, -1] / ray[:, -1]  # determine lambda
      dot = tf.expand_dims(l, -1) * ray + t_inv
      dot = tf.concat([dot, tf.ones([dot.shape[0], 1, 1])], axis=1)
      outputs["dot"] = dot
  
      # 3D Bounding Box: Size3D, Center3D (relative to dot), Rotation_z
      batch_size = dot.shape[0]
      size3d_prior = tf.cast([[1, 1, 1.5]], dtype=tf.float32)
      size3d_prior = tf.tile(size3d_prior, [batch_size, 1])
      outputs["size3d"] = size3d_prior + object_size
      center3d_prior = dot[:, 0:3, 0]
      outputs["center3d"] = center3d_prior + object_translation
      # Estimate rotation parameters using https://arxiv.org/abs/2006.14616
      rotation_prior = tf.eye(2, batch_shape=[batch_size])
      invalid_rotation = rotation_prior + tf.reshape(
          object_rotation, [-1, 2, 2]
      )
      s, u, v = tf.linalg.svd(invalid_rotation)
      det = tf.linalg.det(tf.matmul(u, tf.linalg.matrix_transpose(v)))
      det = tf.reshape(det, [-1, 1])
      s = tf.linalg.diag(tf.concat([tf.ones(det.shape), det], axis=1))
      outputs["rotation"] = tf.matmul(
          u, tf.matmul(s, v, adjoint_b=True)
      )
  
      # 2D Bounding Box: Center2D
      center2d_prior = tf.cast(
          inputs["image_size"][0, 0:2] / 2, dtype=tf.float32
      )
      predicted_center2d = center2d_prior + predicted_center2d_offset
      outputs["center2d"] = predicted_center2d
  
      # 2D Bounding Box: Size2D
      size2d_prior = tf.cast([100, 150], dtype=tf.float32)
      outputs["size2d"] = size2d_prior + predicted_size2d_offset
  
      return outputs
  
imports: import math
  import tensorflow
label_desc: Use image node_id 5 for calling the SingleObjectModel obj's underlying member method code with example usage: obj.decode_predictions(predictions, inputs, outputs) and returns: outputs