class_docstr: Class to manage random ray spatial sampling.
  
  Args:
      min_depth: sampled rays minimal depth from cameras: float
      max_depth: sampled rays maximal depth from cameras: float
      ndc: convert to normalized device coordinates: bool
      device: device for ray tensors: Union[str, torch.device]
docstr: Randomly sample pixel points in 2d.
  
  Args:
      heights: tensor that holds scene camera image heights (can vary between cameras): math: `(B)`.
      widths: tensor that holds scene camera image widths (can vary between cameras): math: `(B)`.
      num_img_rays: tensor that holds the number of rays to randomly cast from each scene camera: math: `(B)`.
  
  Returns:
      dictionary of Points2D objects that holds information on pixel 2d coordinates of each ray and the camera
        id it was casted by: Dict[int, Points2D]
docstr_tok: ["Randomly","sample","pixel","points","in","2d",".","Args",":","heights",":","tensor","that","holds","scene","camera","image","heights","(","can","vary","between","cameras",")",":","math",":","`","(","B",")","`",".","widths",":","tensor","that","holds","scene","camera","image","widths","(","can","vary","between","cameras",")",":","math",":","`","(","B",")","`",".","num_img_rays",":","tensor","that","holds","the","number","of","rays","to","randomly","cast","from","each","scene","camera",":","math",":","`","(","B",")","`",".","Returns",":","dictionary","of","Points2D","objects","that","holds","information","on","pixel","2d","coordinates","of","each","ray","and","the","camera","id","it","was","casted","by",":","Dict","[","int",",","Points2D","]"]
code: def sample_points_2d(
      self, heights: Tensor, widths: Tensor, num_img_rays: Tensor
  ) -> Dict[int, RaySampler.Points2D]:
      r"""Randomly sample pixel points in 2d.
  
      Args:
          heights: tensor that holds scene camera image heights (can vary between cameras): math: `(B)`.
          widths: tensor that holds scene camera image widths (can vary between cameras): math: `(B)`.
          num_img_rays: tensor that holds the number of rays to randomly cast from each scene camera: math: `(B)`.
  
      Returns:
          dictionary of Points2D objects that holds information on pixel 2d coordinates of each ray and the camera
            id it was casted by: Dict[int, Points2D]
      """
      num_img_rays = num_img_rays.int()
      points2d_as_flat_tensors: Dict[
          int, RaySampler.Points2D_FlatTensors
      ] = {}
      for camera_id, (height, width, n) in enumerate(
          zip(heights.tolist(), widths.tolist(), num_img_rays.tolist())
      ):
          y_rand = torch.trunc(
              torch.rand(n, device=self._device, dtype=self._dtype)
              * height
          )
          x_rand = torch.trunc(
              torch.rand(n, device=self._device, dtype=self._dtype)
              * width
          )
          RaySampler._add_points2d_as_flat_tensors_to_num_ray_dict(
              n, x_rand, y_rand, camera_id, points2d_as_flat_tensors
          )
      return RaySampler._build_num_ray_dict_of_points2d(
          points2d_as_flat_tensors
      )
  
imports: import math
  from typing import Dict, List, Tuple
  import torch
  from kornia.core import Device, Tensor, tensor
  from kornia.geometry.camera import PinholeCamera
  from kornia.nerf.camera_utils import cameras_for_ids
  from kornia.utils._compat import torch_meshgrid
  from kornia.utils.helpers import _torch_inverse_cast
label_desc: Use image node_id 2 for calling the RandomRaySampler obj's underlying member method code with example usage: obj.sample_points_2d(heights, widths, num_img_rays) and returns: RaySampler