class_docstr: Rotate the input inside the input's frame by an angle selected randomly from the uniform distribution.
  
  The resulting image may have artifacts in it. After rotation, the image may have a different aspect ratio, and
  after resizing, it returns to its original shape with the original aspect ratio of the image. For these reason we
  may see some artifacts.
  
  Args:
      limit ((int, int) or int): range from which a random angle is picked. If limit is a single int
          an angle is picked from (-limit, limit). Default: (-90, 90)
      interpolation (OpenCV flag): flag that is used to specify the interpolation algorithm. Should be one of:
          cv2.INTER_NEAREST, cv2.INTER_LINEAR, cv2.INTER_CUBIC, cv2.INTER_AREA, cv2.INTER_LANCZOS4.
          Default: cv2.INTER_LINEAR.
      border_mode (OpenCV flag): flag that is used to specify the pixel extrapolation method. Should be one of:
          cv2.BORDER_CONSTANT, cv2.BORDER_REPLICATE, cv2.BORDER_REFLECT, cv2.BORDER_WRAP, cv2.BORDER_REFLECT_101.
          Default: cv2.BORDER_REFLECT_101
      value (int, float, list of ints, list of float): padding value if border_mode is cv2.BORDER_CONSTANT.
      mask_value (int, float,
                  list of ints,
                  list of float): padding value if border_mode is cv2.BORDER_CONSTANT applied for masks.
      p (float): probability of applying the transform. Default: 0.5.
  
  Targets:
      image, mask, bboxes, keypoints
  
  Image types:
      uint8, float32
code: def get_params_dependent_on_targets(
      self, params: Dict[str, Any]
  ) -> Dict[str, Any]:
      angle = random.uniform(self.limit[0], self.limit[1])
  
      image = params["image"]
      h, w = image.shape[:2]
  
      # https://stackoverflow.com/questions/43892506/opencv-python-rotate-image-without-cropping-sides
      image_center = (w / 2, h / 2)
  
      # Rotation Matrix
      rotation_mat = cv2.getRotationMatrix2D(image_center, angle, 1.0)
  
      # rotation calculates the cos and sin, taking absolutes of those.
      abs_cos = abs(rotation_mat[0, 0])
      abs_sin = abs(rotation_mat[0, 1])
  
      # find the new width and height bounds
      new_w = math.ceil(h * abs_sin + w * abs_cos)
      new_h = math.ceil(h * abs_cos + w * abs_sin)
  
      scale_x = w / new_w
      scale_y = h / new_h
  
      # Shift the image to create padding
      rotation_mat[0, 2] += new_w / 2 - image_center[0]
      rotation_mat[1, 2] += new_h / 2 - image_center[1]
  
      # Rescale to original size
      scale_mat = np.diag(np.ones(3))
      scale_mat[0, 0] *= scale_x
      scale_mat[1, 1] *= scale_y
      _tmp = np.diag(np.ones(3))
      _tmp[:2] = rotation_mat
      _tmp = scale_mat @ _tmp
      rotation_mat = _tmp[:2]
  
      return {
          "matrix": rotation_mat,
          "angle": angle,
          "scale_x": scale_x,
          "scale_y": scale_y,
      }
  
imports: import math
  import random
  from typing import Any, Dict, List, Optional, Sequence, Tuple, Union
  import cv2
  import numpy
  from ...core.transforms_interface import BoxInternalType, DualTransform, FillValueType, KeypointInternalType, to_tuple
  from ..crops import functional
  from .None import functional
label_desc: Use image node_id 7 for calling the SafeRotate obj's underlying member method code with example usage: obj.get_params_dependent_on_targets(params) and returns: dict