docs: def preprocess_images(raw_color_im,
                        raw_depth_im,
                        camera_intr,
                        T_camera_world,
                        workspace_box,
                        workspace_im,
                        image_proc_config):
      """ Preprocess a set of color and depth images. """
      # read params
      inpaint_rescale_factor = image_proc_config['inpaint_rescale_factor']
      cluster = image_proc_config['cluster']
      cluster_tolerance = image_proc_config['cluster_tolerance']
      min_cluster_size = image_proc_config['min_cluster_size']
      max_cluster_size = image_proc_config['max_cluster_size']
  
      # deproject into 3D world coordinates
      point_cloud_cam = camera_intr.deproject(raw_depth_im)
      point_cloud_cam.remove_zero_points()
      point_cloud_world = T_camera_world * point_cloud_cam
  
      # compute the segmask for points above the box
      seg_point_cloud_world, _ = point_cloud_world.box_mask(workspace_box)
      seg_point_cloud_cam = T_camera_world.inverse() * seg_point_cloud_world
      depth_im_seg = camera_intr.project_to_image(seg_point_cloud_cam)
  
      # mask out objects in the known workspace
      env_pixels = depth_im_seg.pixels_farther_than(workspace_im)
      depth_im_seg._data[env_pixels[:,0], env_pixels[:,1]] = 0
  
      # REMOVE NOISE
      # clip low points
      low_indices = np.where(point_cloud_world.data[2,:] < workspace_box.min_pt[2])[0] 
      point_cloud_world.data[2,low_indices] = workspace_box.min_pt[2]
              
      # clip high points
      high_indices = np.where(point_cloud_world.data[2,:] > workspace_box.max_pt[2])[0] 
      point_cloud_world.data[2,high_indices] = workspace_box.max_pt[2]
  
      # segment out the region in the workspace (including the table)
      workspace_point_cloud_world, valid_indices = point_cloud_world.box_mask(workspace_box)
      invalid_indices = np.setdiff1d(np.arange(point_cloud_world.num_points),
                                     valid_indices)
  
      if cluster:
          # create new cloud
          pcl_cloud = pcl.PointCloud(workspace_point_cloud_world.data.T.astype(np.float32))
          tree = pcl_cloud.make_kdtree()
      
          # find large clusters (likely to be real objects instead of noise)
          ec = pcl_cloud.make_EuclideanClusterExtraction()
          ec.set_ClusterTolerance(cluster_tolerance)
          ec.set_MinClusterSize(min_cluster_size)
          ec.set_MaxClusterSize(max_cluster_size)
          ec.set_SearchMethod(tree)
          cluster_indices = ec.Extract()
          num_clusters = len(cluster_indices)
  
          # read out all points in large clusters
          filtered_points = np.zeros([3,workspace_point_cloud_world.num_points])
          cur_i = 0
          for j, indices in enumerate(cluster_indices):
              num_points = len(indices)
              points = np.zeros([3,num_points])
      
              for i, index in enumerate(indices):
                  points[0,i] = pcl_cloud[index][0]
                  points[1,i] = pcl_cloud[index][1]
                  points[2,i] = pcl_cloud[index][2]
  
              filtered_points[:,cur_i:cur_i+num_points] = points.copy()
              cur_i = cur_i + num_points
  
          # reconstruct the point cloud
          all_points = np.c_[filtered_points[:,:cur_i], point_cloud_world.data[:,invalid_indices]]
      else:
          all_points = point_cloud_world.data
      filtered_point_cloud_world = PointCloud(all_points,
                                              frame='world')  
  
      # compute the filtered depth image
      filtered_point_cloud_cam = T_camera_world.inverse() * filtered_point_cloud_world
      depth_im = camera_intr.project_to_image(filtered_point_cloud_cam)    
  
      # form segmask
      segmask = depth_im_seg.to_binary()
      valid_px_segmask = depth_im.invalid_pixel_mask().inverse()
      segmask = segmask.mask_binary(valid_px_segmask)
      
      # inpaint
      color_im = raw_color_im.inpaint(rescale_factor=inpaint_rescale_factor)
      depth_im = depth_im.inpaint(rescale_factor=inpaint_rescale_factor)    
      return color_im, depth_im, segmask