class_docstr: Randomly crop images and make sure to contain at least one intact
  instance.
  
  Required Keys:
  
  - img
  - gt_polygons
  - gt_bboxes
  - gt_bboxes_labels
  - gt_ignored
  - gt_texts (optional)
  
  Modified Keys:
  
  - img
  - img_shape
  - gt_polygons
  - gt_bboxes
  - gt_bboxes_labels
  - gt_ignored
  - gt_texts (optional)
  
  Args:
      min_side_ratio (float): The ratio of the shortest edge of the cropped
          image to the original image size.
class_docstr_tok: ["Randomly","crop","images","and","make","sure","to","contain","at","least","one","intact","instance",".","Required","Keys",":","-","img","-","gt_polygons","-","gt_bboxes","-","gt_bboxes_labels","-","gt_ignored","-","gt_texts","(","optional",")","Modified","Keys",":","-","img","-","img_shape","-","gt_polygons","-","gt_bboxes","-","gt_bboxes_labels","-","gt_ignored","-","gt_texts","(","optional",")","Args",":","min_side_ratio","(","float",")",":","The","ratio","of","the","shortest","edge","of","the","cropped","image","to","the","original","image","size","."]
docstr: Sample a start and end idx on a given axis that contains at least
  one polygon. There should be at least one intact polygon bounded by
  max_start_idx and min_end_idx.
  
  Args:
      valid_array (ndarray): A 0-1 mask 1D array indicating valid regions
          on the axis. 0 indicates text regions which are not allowed to
          be sampled from.
      min_len (int): Minimum distance between two start and end points.
      max_start_idx (int): The maximum start index.
      min_end_idx (int): The minimum end index.
  
  Returns:
      tuple(int, int): Start and end index on a given axis, where
      0 <= start < max_start_idx and
      min_end_idx <= end < len(valid_array).
docstr_tok: ["Sample","a","start","and","end","idx","on","a","given","axis","that","contains","at","least","one","polygon",".","There","should","be","at","least","one","intact","polygon","bounded","by","max_start_idx","and","min_end_idx",".","Args",":","valid_array","(","ndarray",")",":","A","0-1","mask","1D","array","indicating","valid","regions","on","the","axis",".","0","indicates","text","regions","which","are","not","allowed","to","be","sampled","from",".","min_len","(","int",")",":","Minimum","distance","between","two","start","and","end","points",".","max_start_idx","(","int",")",":","The","maximum","start","index",".","min_end_idx","(","int",")",":","The","minimum","end","index",".","Returns",":","tuple","(","int",",","int",")",":","Start","and","end","index","on","a","given","axis",",","where","0","<","=","start","<","max_start_idx","and","min_end_idx","<","=","end","<","len","(","valid_array",")","."]
code: def _sample_valid_start_end(
      self,
      valid_array: np.ndarray,
      min_len: int,
      max_start_idx: int,
      min_end_idx: int,
  ) -> Tuple[int, int]:
      """Sample a start and end idx on a given axis that contains at least
      one polygon. There should be at least one intact polygon bounded by
      max_start_idx and min_end_idx.
  
      Args:
          valid_array (ndarray): A 0-1 mask 1D array indicating valid regions
              on the axis. 0 indicates text regions which are not allowed to
              be sampled from.
          min_len (int): Minimum distance between two start and end points.
          max_start_idx (int): The maximum start index.
          min_end_idx (int): The minimum end index.
  
      Returns:
          tuple(int, int): Start and end index on a given axis, where
          0 <= start < max_start_idx and
          min_end_idx <= end < len(valid_array).
      """
      assert isinstance(min_len, int)
      assert len(valid_array) > min_len
  
      start_array = valid_array.copy()
      max_start_idx = min(len(start_array) - min_len, max_start_idx)
      start_array[max_start_idx:] = 0
      start_array[0] = 1
      diff_array = np.hstack([0, start_array]) - np.hstack(
          [start_array, 0]
      )
      region_starts = np.where(diff_array < 0)[0]
      region_ends = np.where(diff_array > 0)[0]
      region_ind = np.random.randint(0, len(region_starts))
      start = np.random.randint(
          region_starts[region_ind], region_ends[region_ind]
      )
  
      end_array = valid_array.copy()
      min_end_idx = max(start + min_len, min_end_idx)
      end_array[:min_end_idx] = 0
      end_array[-1] = 1
      diff_array = np.hstack([0, end_array]) - np.hstack([end_array, 0])
      region_starts = np.where(diff_array < 0)[0]
      region_ends = np.where(diff_array > 0)[0]
      region_ind = np.random.randint(0, len(region_starts))
      # Note that end index will never be region_ends[region_ind]
      # and therefore end index is always in range [0, w+1]
      end = np.random.randint(
          region_starts[region_ind], region_ends[region_ind]
      )
      return start, end
  
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 2 for calling the RandomCrop obj's underlying member method code with example usage: obj._sample_valid_start_end(valid_array, min_len, max_start_idx, min_end_idx) and returns: start,  end