code: def single_object_reproject(
      bbox_3d=None,
      pt=None,
      pt_segments=None,
      camera=None,
      cam_positions=None,
      num_frames=None,
      depth_map=None,
      segments=None,
      window=None,
      input_size=None,
      quat=None,
      normals=None,
      frame_for_pt=None,
      trust_normals=None,
  ):
      """Reproject points for a single object.
  
      Args:
        bbox_3d: The object bounding box from Kubric.  If none, assume it's
          background.
        pt: The set of points in 3D, with shape [num_points, 3]
        pt_segments: The segment each point came from, with shape [num_points]
        camera: Camera intrinsic parameters
        cam_positions: Camera positions, with shape [num_frames, 3]
        num_frames: Number of frames
        depth_map: Depth map video for the camera
        segments: Segmentation map video for the camera
        window: the window inside which we're sampling points
        input_size: [height, width] of the input images.
        quat: Object quaternion [num_frames, 4]
        normals: Point normals on the query frame [num_points, 3]
        frame_for_pt: Integer frame where the query point came from [num_points]
        trust_normals: Boolean flag for whether the surface normals for each query
          are trustworthy [num_points]
  
      Returns:
        Position for each point, of shape [num_points, num_frames, 2], in pixel
        coordinates, and an occlusion flag for each point, of shape
        [num_points, num_frames].  These are respect to the image frame, not the
        window.
  
      """
      # Finally, reproject
      reproj, depth_proj, world_pos = reproject(
          pt,
          camera,
          cam_positions,
          num_frames,
          bbox=bbox_3d,
      )
  
      occluded = tf.less(reproj[:, :, 2], 0)
      reproj = (
          reproj[:, :, 0:2]
          * np.array(input_size[::-1])[np.newaxis, np.newaxis, :]
      )
      occluded = tf.logical_or(
          occluded,
          estimate_occlusion_by_depth_and_segment(
              depth_map[:, :, :, 0],
              segments[:, :, :, 0],
              tf.transpose(reproj[:, :, 0]),
              tf.transpose(reproj[:, :, 1]),
              num_frames,
              depth_proj * 0.99,
              pt_segments,
          ),
      )
      obj_occ = occluded
      obj_reproj = reproj
  
      obj_occ = tf.logical_or(
          obj_occ, tf.less(obj_reproj[:, :, 1], window[0])
      )
      obj_occ = tf.logical_or(
          obj_occ, tf.less(obj_reproj[:, :, 0], window[1])
      )
      obj_occ = tf.logical_or(
          obj_occ, tf.greater(obj_reproj[:, :, 1], window[2])
      )
      obj_occ = tf.logical_or(
          obj_occ, tf.greater(obj_reproj[:, :, 0], window[3])
      )
  
      if quat is not None:
          faces_away = rotate_surface_normals(
              normals,
              world_pos,
              cam_positions,
              quat2rot(quat),
              frame_for_pt,
          )
          faces_away = tf.logical_and(faces_away, trust_normals)
      else:
          # world is convex; can't face away from cam.
          faces_away = tf.zeros(
              [tf.shape(pt)[0], num_frames], dtype=tf.bool
          )
  
      return obj_reproj, tf.logical_or(faces_away, obj_occ)
  
imports: import functools
  import itertools
  import matplotlib.pyplot
  import mediapy
  import numpy
  import tensorflow.compat.v1
  import tensorflow_datasets
  from tensorflow_graphics.geometry.transformation import rotation_matrix_3d
label_desc: Use image node_id 8 for calling a global function with example usage: single_object_reproject(bbox_3d, pt, pt_segments, camera, cam_positions, num_frames, depth_map, segments, window, input_size, quat, normals, frame_for_pt, trust_normals) and returns: obj_reproj,  tf