class_docstr: Class to handle camera geometry.
class_docstr_tok: ["Class","to","handle","camera","geometry","."]
docstr: Projects a 3D point (x,y,z) to a pixel position (x,y).
docstr_tok: ["Projects","a","3D","point","(","x",",","y",",","z",")","to","a","pixel","position","(","x",",","y",")","."]
code: def project(self, points: np.ndarray):
      """Projects a 3D point (x,y,z) to a pixel position (x,y)."""
      batch_shape = points.shape[:-1]
      points = points.reshape((-1, 3))
      local_points = self.points_to_local_points(points)
  
      # Get normalized local pixel positions.
      x = local_points[..., 0] / local_points[..., 2]
      y = local_points[..., 1] / local_points[..., 2]
      r2 = x**2 + y**2
  
      # Apply radial distortion.
      distortion = 1.0 + r2 * (
          self.radial_distortion[0]
          + r2
          * (self.radial_distortion[1] + self.radial_distortion[2] * r2)
      )
  
      # Apply tangential distortion.
      x_times_y = x * y
      x = (
          x * distortion
          + 2.0 * self.tangential_distortion[0] * x_times_y
          + self.tangential_distortion[1] * (r2 + 2.0 * x**2)
      )
      y = (
          y * distortion
          + 2.0 * self.tangential_distortion[1] * x_times_y
          + self.tangential_distortion[0] * (r2 + 2.0 * y**2)
      )
  
      # Map the distorted ray to the image plane and return the depth.
      pixel_x = (
          self.focal_length * x + self.skew * y + self.principal_point_x
      )
      pixel_y = (
          self.focal_length * self.pixel_aspect_ratio * y
          + self.principal_point_y
      )
  
      pixels = np.stack([pixel_x, pixel_y], axis=-1)
      return pixels.reshape((*batch_shape, 2))
  
imports: import copy
  import json
  from typing import Tuple, Union, Optional
  import numpy
  from nerfies import gpath
  from nerfies import types
label_desc: Use image node_id 20 for calling the Camera obj's underlying member method code with example usage: obj.project(points) and returns: pixels