code: def rotate_perturbation_point_cloud(
      batch_data, angle_sigma=0.06, angle_clip=0.18
  ):
      """Randomly perturb the point clouds by small rotations
      Input:
        BxNx3 array, original batch of point clouds
      Return:
        BxNx3 array, rotated batch of point clouds
      """
      rotated_data = np.zeros(batch_data.shape, dtype=np.float32)
      for k in range(batch_data.shape[0]):
          angles = np.clip(
              angle_sigma * np.random.randn(3), -angle_clip, angle_clip
          )
          Rx = np.array(
              [
                  [1, 0, 0],
                  [0, np.cos(angles[0]), -np.sin(angles[0])],
                  [0, np.sin(angles[0]), np.cos(angles[0])],
              ]
          )
          Ry = np.array(
              [
                  [np.cos(angles[1]), 0, np.sin(angles[1])],
                  [0, 1, 0],
                  [-np.sin(angles[1]), 0, np.cos(angles[1])],
              ]
          )
          Rz = np.array(
              [
                  [np.cos(angles[2]), -np.sin(angles[2]), 0],
                  [np.sin(angles[2]), np.cos(angles[2]), 0],
                  [0, 0, 1],
              ]
          )
          R = np.dot(Rz, np.dot(Ry, Rx))
          shape_pc = batch_data[k, ...]
          rotated_data[k, ...] = np.dot(shape_pc.reshape((-1, 3)), R)
      return rotated_data
  
imports: from lavis.common.registry import registry
  from lavis.processors.blip_processors import BlipImageBaseProcessor
  from omegaconf import OmegaConf
  import torchvision.transforms
  from lavis.models.ulip_models.utils.io import IO
  import numpy
  from PIL import Image
  import torch
label_desc: Use image node_id 11 for calling a global function with example usage: rotate_perturbation_point_cloud(batch_data, angle_sigma, angle_clip) and returns: rotated_data