class_docstr: Random crop and flip a patch in the image. Only used in text detection
  task.
  
  Required Keys:
  
  - img
  - gt_bboxes
  - gt_polygons
  
  Modified Keys:
  
  - img
  - gt_bboxes
  - gt_polygons
  
  Args:
      pad_ratio (float): The ratio of padding. Defaults to 0.1.
      crop_ratio (float): The ratio of cropping. Defaults to 0.5.
      iter_num (int): Number of operations. Defaults to 1.
      min_area_ratio (float): Minimal area ratio between cropped patch
          and original image. Defaults to 0.2.
      epsilon (float): The threshold of polygon IoU between cropped area
          and polygon, which is used to avoid cropping text instances.
          Defaults to 0.01.
docstr: Applying random crop flip on polygons.
  
  Args:
      results (dict): Result dict containing the data to transform
  
  Returns:
      dict: The transformed data
docstr_tok: ["Applying","random","crop","flip","on","polygons",".","Args",":","results","(","dict",")",":","Result","dict","containing","the","data","to","transform","Returns",":","dict",":","The","transformed","data"]
code: def _random_crop_flip_polygons(self, results: Dict) -> Dict:
      """Applying random crop flip on polygons.
  
      Args:
          results (dict): Result dict containing the data to transform
  
      Returns:
          dict: The transformed data
      """
      if results.get("gt_polygons", None) is None:
          return results
  
      image = results["img"]
      polygons = results["gt_polygons"]
      if len(polygons) == 0 or self._random_prob() > self.crop_ratio:
          return results
  
      h, w = results["img_shape"]
      area = h * w
      pad_h = int(h * self.pad_ratio)
      pad_w = int(w * self.pad_ratio)
      h_axis, w_axis = self._generate_crop_target(
          image, polygons, pad_h, pad_w
      )
      if len(h_axis) == 0 or len(w_axis) == 0:
          return results
  
      # At most 10 attempts
      for _ in range(10):
          polys_keep = []
          polys_new = []
          kept_idxs = []
          xx = self._random_choice(w_axis)
          yy = self._random_choice(h_axis)
          xmin = np.clip(np.min(xx) - pad_w, 0, w - 1)
          xmax = np.clip(np.max(xx) - pad_w, 0, w - 1)
          ymin = np.clip(np.min(yy) - pad_h, 0, h - 1)
          ymax = np.clip(np.max(yy) - pad_h, 0, h - 1)
          if (xmax - xmin) * (ymax - ymin) < area * self.min_area_ratio:
              # Skip when cropped area is too small
              continue
  
          pts = np.stack(
              [[xmin, xmax, xmax, xmin], [ymin, ymin, ymax, ymax]]
          ).T.astype(np.int32)
          pp = plg(pts)
          success_flag = True
          for poly_idx, polygon in enumerate(polygons):
              ppi = plg(polygon.reshape(-1, 2))
              ppiou = poly_intersection(ppi, pp)
              if (
                  np.abs(ppiou - float(ppi.area)) > self.epsilon
                  and np.abs(ppiou) > self.epsilon
              ):
                  success_flag = False
                  break
              kept_idxs.append(poly_idx)
              if np.abs(ppiou - float(ppi.area)) < self.epsilon:
                  polys_new.append(polygon)
              else:
                  polys_keep.append(polygon)
  
          if success_flag:
              break
  
      cropped = image[ymin:ymax, xmin:xmax, :]
      select_type = self._random_flip_type()
      if select_type == 0:
          img = np.ascontiguousarray(cropped[:, ::-1])
      elif select_type == 1:
          img = np.ascontiguousarray(cropped[::-1, :])
      else:
          img = np.ascontiguousarray(cropped[::-1, ::-1])
      image[ymin:ymax, xmin:xmax, :] = img
      results["img"] = image
  
      if len(polys_new) != 0:
          height, width, _ = cropped.shape
          if select_type == 0:
              for idx, polygon in enumerate(polys_new):
                  poly = polygon.reshape(-1, 2)
                  poly[:, 0] = width - poly[:, 0] + 2 * xmin
                  polys_new[idx] = poly.reshape(
                      -1,
                  )
          elif select_type == 1:
              for idx, polygon in enumerate(polys_new):
                  poly = polygon.reshape(-1, 2)
                  poly[:, 1] = height - poly[:, 1] + 2 * ymin
                  polys_new[idx] = poly.reshape(
                      -1,
                  )
          else:
              for idx, polygon in enumerate(polys_new):
                  poly = polygon.reshape(-1, 2)
                  poly[:, 0] = width - poly[:, 0] + 2 * xmin
                  poly[:, 1] = height - poly[:, 1] + 2 * ymin
                  polys_new[idx] = poly.reshape(
                      -1,
                  )
          polygons = polys_keep + polys_new
          # ignored = polys_keep_ignore_idx + polys_new_ignore_idx
          results["gt_polygons"] = polygons
          results["gt_ignored"] = results["gt_ignored"][kept_idxs]
          results["gt_bboxes_labels"] = results["gt_bboxes_labels"][
              kept_idxs
          ]
      return results
  
imports: import math
  import random
  from typing import Dict, List, Sequence, Tuple, Union
  import cv2
  import mmcv
  import numpy
  from mmcv.transforms import RandomFlip
  from mmcv.transforms.base import BaseTransform
  from mmcv.transforms.utils import avoid_cache_randomness, cache_randomness
  from shapely.geometry import Polygon
  from mmocr.registry import TRANSFORMS
  from mmocr.utils import crop_polygon, poly2bbox, poly_intersection
label_desc: Use image node_id 6 for calling the TextDetRandomCropFlip obj's underlying member method code with example usage: obj._random_crop_flip_polygons(results) and returns: results, results, results, results