class_docstr: A general geometric augmentation tool for text images in the CVPR 2020
  paper "Learn to Augment: Joint Data Augmentation and Network Optimization
  for Text Recognition". It applies distortion, stretching, and perspective
  transforms to an image.
  
  This implementation is adapted from
  https://github.com/RubanSeven/Text-Image-Augmentation-python/blob/master/augment.py  # noqa
  
  TODO: Split this transform into three transforms.
  
  Required Keys:
  
  - img
  
  Modified Keys:
  
  - img
  - img_shape
class_docstr_tok: ["A","general","geometric","augmentation","tool","for","text","images","in","the","CVPR","2020","paper","``","Learn","to","Augment",":","Joint","Data","Augmentation","and","Network","Optimization","for","Text","Recognition","''",".","It","applies","distortion",",","stretching",",","and","perspective","transforms","to","an","image",".","This","implementation","is","adapted","from","https",":","\/\/github.com\/RubanSeven\/Text-Image-Augmentation-python\/blob\/master\/augment.py","#","noqa","TODO",":","Split","this","transform","into","three","transforms",".","Required","Keys",":","-","img","Modified","Keys",":","-","img","-","img_shape"]
docstr: Compute delta.
docstr_tok: ["Compute","delta","."]
code: def _calc_delta(
      self,
      dst_w: int,
      dst_h: int,
      src_pts: List[int],
      dst_pts: List[int],
      grid_size: int,
  ) -> Tuple[np.ndarray, np.ndarray]:
      """Compute delta."""
  
      pt_count = len(dst_pts)
      rdx = np.zeros((dst_h, dst_w))
      rdy = np.zeros((dst_h, dst_w))
      w = np.zeros(pt_count, dtype=np.float32)
  
      if pt_count < 2:
          return
  
      i = 0
      while True:
          if dst_w <= i < dst_w + grid_size - 1:
              i = dst_w - 1
          elif i >= dst_w:
              break
  
          j = 0
          while True:
              if dst_h <= j < dst_h + grid_size - 1:
                  j = dst_h - 1
              elif j >= dst_h:
                  break
  
              sw = 0
              swp = np.zeros(2, dtype=np.float32)
              swq = np.zeros(2, dtype=np.float32)
              new_pt = np.zeros(2, dtype=np.float32)
              cur_pt = np.array([i, j], dtype=np.float32)
  
              k = 0
              for k in range(pt_count):
                  if i == dst_pts[k][0] and j == dst_pts[k][1]:
                      break
  
                  w[k] = 1.0 / (
                      (i - dst_pts[k][0]) * (i - dst_pts[k][0])
                      + (j - dst_pts[k][1]) * (j - dst_pts[k][1])
                  )
  
                  sw += w[k]
                  swp = swp + w[k] * np.array(dst_pts[k])
                  swq = swq + w[k] * np.array(src_pts[k])
  
              if k == pt_count - 1:
                  pstar = 1 / sw * swp
                  qstar = 1 / sw * swq
  
                  miu_s = 0
                  for k in range(pt_count):
                      if i == dst_pts[k][0] and j == dst_pts[k][1]:
                          continue
                      pt_i = dst_pts[k] - pstar
                      miu_s += w[k] * np.sum(pt_i * pt_i)
  
                  cur_pt -= pstar
                  cur_pt_j = np.array([-cur_pt[1], cur_pt[0]])
  
                  for k in range(pt_count):
                      if i == dst_pts[k][0] and j == dst_pts[k][1]:
                          continue
  
                      pt_i = dst_pts[k] - pstar
                      pt_j = np.array([-pt_i[1], pt_i[0]])
  
                      tmp_pt = np.zeros(2, dtype=np.float32)
                      tmp_pt[0] = (
                          np.sum(pt_i * cur_pt) * src_pts[k][0]
                          - np.sum(pt_j * cur_pt) * src_pts[k][1]
                      )
                      tmp_pt[1] = (
                          -np.sum(pt_i * cur_pt_j) * src_pts[k][0]
                          + np.sum(pt_j * cur_pt_j) * src_pts[k][1]
                      )
                      tmp_pt *= w[k] / miu_s
                      new_pt += tmp_pt
  
                  new_pt += qstar
              else:
                  new_pt = src_pts[k]
  
              rdx[j, i] = new_pt[0] - i
              rdy[j, i] = new_pt[1] - j
  
              j += grid_size
          i += grid_size
      return rdx, rdy
  
imports: import math
  import random
  from typing import Dict, List, Optional, Tuple
  import cv2
  import mmcv
  import numpy
  from mmcv.transforms.base import BaseTransform
  from mmcv.transforms.utils import cache_randomness
  from mmocr.registry import TRANSFORMS
label_desc: Use image node_id 7 for calling the TextRecogGeneralAug obj's underlying member method code with example usage: obj._calc_delta(dst_w, dst_h, src_pts, dst_pts, grid_size) and returns: rdx,  rdy