docstr: the function signature is not fully correct, because img is an optional
  if cam2world is None, the output pcd is in camera space, else the out pcd is in world space.
  here the output is pure np array
docstr_tok: ["the","function","signature","is","not","fully","correct",",","because","img","is","an","optional","if","cam2world","is","None",",","the","output","pcd","is","in","camera","space",",","else","the","out","pcd","is","in","world","space",".","here","the","output","is","pure","np","array"]
code: def img_to_pcd_3d(depth, intrinsic, img=None, cam2world=None):
      """
      the function signature is not fully correct, because img is an optional
      if cam2world is None, the output pcd is in camera space, else the out pcd is in world space.
      here the output is pure np array
      """
  
      assert isinstance(
          depth, np.ndarray
      ), f"cannot process data type: {type(depth)}"
      assert len(depth.shape) == 2
      assert isinstance(
          intrinsic, np.ndarray
      ), f"cannot process data type: {type(intrinsic)}"
      assert intrinsic.shape == (3, 3)
      if img is not None:
          assert isinstance(
              img, np.ndarray
          ), f"cannot process data type: {type(img)}"
          assert len(img.shape) == 3
          assert (
              img.shape[:2] == depth.shape[:2]
          ), "feature should have the same resolution as the depth"
      if cam2world is not None:
          assert isinstance(
              cam2world, np.ndarray
          ), f"cannot process data type: {type(cam2world)}"
          assert cam2world.shape == (4, 4)
  
      pcd_image_space = PointCloudProjectorNp.img_to_pcd_2d(
          depth[..., None], norm_coord=False
      )
      valid_mask_1 = np.where(pcd_image_space[:, 2] > 0)
      pcd_image_space = pcd_image_space[valid_mask_1]
      xy = pcd_image_space[:, :2]
      z = pcd_image_space[:, 2:3]
      if img is not None:
          _c = img.shape[-1]
          feat = img.reshape(-1, _c)
          feat = feat[valid_mask_1]
          xy = np.concatenate([xy, feat], axis=1)
      pcd_3d = PointCloudProjectorNp.pcd_2d_to_pcd_3d(
          xy, z, intrinsic, cam2world=cam2world
      )
      return pcd_3d
  
file_path: ml-neuman/geometry/pcd_projector.py
imports: import numpy
  import torch
label_desc: Use image node_id 3 for calling the PointCloudProjectorNp obj's underlying member method code with example usage: obj.img_to_pcd_3d(depth, intrinsic, img, cam2world) and returns: pcd_3d