class_docstr: Randomly rotate the image, boxes, and polygons. For recognition task,
  only the image will be rotated. If set ``use_canvas`` as True, the shape of
  rotated image might be modified based on the rotated angle size, otherwise,
  the image will keep the shape before rotation.
  
  Required Keys:
  
  - img
  - img_shape
  - gt_bboxes (optional)
  - gt_polygons (optional)
  
  Modified Keys:
  
  - img
  - img_shape (optional)
  - gt_bboxes (optional)
  - gt_polygons (optional)
  
  Added Keys:
  
  - rotated_angle
  
  Args:
      max_angle (int): The maximum rotation angle (can be bigger than 180 or
          a negative). Defaults to 10.
      pad_with_fixed_color (bool): The flag for whether to pad rotated
          image with fixed value. Defaults to False.
      pad_value (tuple[int, int, int]): The color value for padding rotated
          image. Defaults to (0, 0, 0).
      use_canvas (bool): Whether to create a canvas for rotated image.
          Defaults to False. If set true, the image shape may be modified.
class_docstr_tok: ["Randomly","rotate","the","image",",","boxes",",","and","polygons",".","For","recognition","task",",","only","the","image","will","be","rotated",".","If","set","``","use_canvas","``","as","True",",","the","shape","of","rotated","image","might","be","modified","based","on","the","rotated","angle","size",",","otherwise",",","the","image","will","keep","the","shape","before","rotation",".","Required","Keys",":","-","img","-","img_shape","-","gt_bboxes","(","optional",")","-","gt_polygons","(","optional",")","Modified","Keys",":","-","img","-","img_shape","(","optional",")","-","gt_bboxes","(","optional",")","-","gt_polygons","(","optional",")","Added","Keys",":","-","rotated_angle","Args",":","max_angle","(","int",")",":","The","maximum","rotation","angle","(","can","be","bigger","than","180","or","a","negative",")",".","Defaults","to","10.","pad_with_fixed_color","(","bool",")",":","The","flag","for","whether","to","pad","rotated","image","with","fixed","value",".","Defaults","to","False",".","pad_value","(","tuple","[","int",",","int",",","int","]",")",":","The","color","value","for","padding","rotated","image",".","Defaults","to","(","0",",","0",",","0",")",".","use_canvas","(","bool",")",":","Whether","to","create","a","canvas","for","rotated","image",".","Defaults","to","False",".","If","set","true",",","the","image","shape","may","be","modified","."]
docstr: Calculate the canvas size.
  
  Args:
      ori_size (Tuple[int, int]): The original image size (height, width)
      degree (int): The rotation angle
  
  Returns:
      Tuple[int, int]: The size of the canvas
docstr_tok: ["Calculate","the","canvas","size",".","Args",":","ori_size","(","Tuple","[","int",",","int","]",")",":","The","original","image","size","(","height",",","width",")","degree","(","int",")",":","The","rotation","angle","Returns",":","Tuple","[","int",",","int","]",":","The","size","of","the","canvas"]
code: def _cal_canvas_size(
      ori_size: Tuple[int, int], degree: int
  ) -> Tuple[int, int]:
      """Calculate the canvas size.
  
      Args:
          ori_size (Tuple[int, int]): The original image size (height, width)
          degree (int): The rotation angle
  
      Returns:
          Tuple[int, int]: The size of the canvas
      """
      assert isinstance(ori_size, tuple)
      angle = degree * math.pi / 180.0
      h, w = ori_size[:2]
  
      cos = math.cos(angle)
      sin = math.sin(angle)
      canvas_h = int(w * math.fabs(sin) + h * math.fabs(cos))
      canvas_w = int(w * math.fabs(cos) + h * math.fabs(sin))
  
      canvas_size = (canvas_h, canvas_w)
      return canvas_size
  
imports: import math
  from typing import Dict, Tuple
  import cv2
  import mmcv
  import numpy
  from mmcv.transforms import Resize
  from mmcv.transforms.base import BaseTransform
  from mmcv.transforms.utils import avoid_cache_randomness, cache_randomness
  from mmocr.registry import TRANSFORMS
  from mmocr.utils import bbox2poly, crop_polygon, is_poly_inside_rect, poly2bbox, poly2shapely, poly_make_valid, remove_pipeline_elements, rescale_polygon, shapely2poly
  from .wrappers import ImgAugWrapper
label_desc: Use image node_id 3 for calling the RandomRotate obj's underlying member method code with example usage: obj._cal_canvas_size(ori_size, degree) and returns: canvas_size