code: def getPoly_core(boxes, labels, mapper, linkmap):
      # configs
      num_cp = 5
      max_len_ratio = 0.7
      expand_ratio = 1.45
      max_r = 2.0
      step_r = 0.2
  
      polys = []
      for k, box in enumerate(boxes):
          # size filter for small instance
          w, h = int(np.linalg.norm(box[0] - box[1]) + 1), int(
              np.linalg.norm(box[1] - box[2]) + 1
          )
          if w < 10 or h < 10:
              polys.append(None)
              continue
  
          # warp image
          tar = np.float32([[0, 0], [w, 0], [w, h], [0, h]])
          M = cv2.getPerspectiveTransform(box, tar)
          word_label = cv2.warpPerspective(
              labels, M, (w, h), flags=cv2.INTER_NEAREST
          )
          try:
              Minv = np.linalg.inv(M)
          except:
              polys.append(None)
              continue
  
          # binarization for selected label
          cur_label = mapper[k]
          word_label[word_label != cur_label] = 0
          word_label[word_label > 0] = 1
  
          """ Polygon generation """
          # find top/bottom contours
          cp = []
          max_len = -1
          for i in range(w):
              region = np.where(word_label[:, i] != 0)[0]
              if len(region) < 2:
                  continue
              cp.append((i, region[0], region[-1]))
              length = region[-1] - region[0] + 1
              if length > max_len:
                  max_len = length
  
          # pass if max_len is similar to h
          if h * max_len_ratio < max_len:
              polys.append(None)
              continue
  
          # get pivot points with fixed length
          tot_seg = num_cp * 2 + 1
          seg_w = w / tot_seg  # segment width
          pp = [None] * num_cp  # init pivot points
          cp_section = [[0, 0]] * tot_seg
          seg_height = [0] * num_cp
          seg_num = 0
          num_sec = 0
          prev_h = -1
          for i in range(0, len(cp)):
              (x, sy, ey) = cp[i]
              if (seg_num + 1) * seg_w <= x and seg_num <= tot_seg:
                  # average previous segment
                  if num_sec == 0:
                      break
                  cp_section[seg_num] = [
                      cp_section[seg_num][0] / num_sec,
                      cp_section[seg_num][1] / num_sec,
                  ]
                  num_sec = 0
  
                  # reset variables
                  seg_num += 1
                  prev_h = -1
  
              # accumulate center points
              cy = (sy + ey) * 0.5
              cur_h = ey - sy + 1
              cp_section[seg_num] = [
                  cp_section[seg_num][0] + x,
                  cp_section[seg_num][1] + cy,
              ]
              num_sec += 1
  
              if seg_num % 2 == 0:
                  continue  # No polygon area
  
              if prev_h < cur_h:
                  pp[int((seg_num - 1) / 2)] = (x, cy)
                  seg_height[int((seg_num - 1) / 2)] = cur_h
                  prev_h = cur_h
  
          # processing last segment
          if num_sec != 0:
              cp_section[-1] = [
                  cp_section[-1][0] / num_sec,
                  cp_section[-1][1] / num_sec,
              ]
  
          # pass if num of pivots is not sufficient or segment width is smaller than character height
          if None in pp or seg_w < np.max(seg_height) * 0.25:
              polys.append(None)
              continue
  
          # calc median maximum of pivot points
          half_char_h = np.median(seg_height) * expand_ratio / 2
  
          # calc gradiant and apply to make horizontal pivots
          new_pp = []
          for i, (x, cy) in enumerate(pp):
              dx = cp_section[i * 2 + 2][0] - cp_section[i * 2][0]
              dy = cp_section[i * 2 + 2][1] - cp_section[i * 2][1]
              if dx == 0:  # gradient if zero
                  new_pp.append(
                      [x, cy - half_char_h, x, cy + half_char_h]
                  )
                  continue
              rad = -math.atan2(dy, dx)
              c, s = half_char_h * math.cos(
                  rad
              ), half_char_h * math.sin(rad)
              new_pp.append([x - s, cy - c, x + s, cy + c])
  
          # get edge points to cover character heatmaps
          isSppFound, isEppFound = False, False
          grad_s = (pp[1][1] - pp[0][1]) / (pp[1][0] - pp[0][0]) + (
              pp[2][1] - pp[1][1]
          ) / (pp[2][0] - pp[1][0])
          grad_e = (pp[-2][1] - pp[-1][1]) / (pp[-2][0] - pp[-1][0]) + (
              pp[-3][1] - pp[-2][1]
          ) / (pp[-3][0] - pp[-2][0])
          for r in np.arange(0.5, max_r, step_r):
              dx = 2 * half_char_h * r
              if not isSppFound:
                  line_img = np.zeros(word_label.shape, dtype=np.uint8)
                  dy = grad_s * dx
                  p = np.array(new_pp[0]) - np.array([dx, dy, dx, dy])
                  cv2.line(
                      line_img,
                      (int(p[0]), int(p[1])),
                      (int(p[2]), int(p[3])),
                      1,
                      thickness=1,
                  )
                  if (
                      np.sum(np.logical_and(word_label, line_img)) == 0
                      or r + 2 * step_r >= max_r
                  ):
                      spp = p
                      isSppFound = True
              if not isEppFound:
                  line_img = np.zeros(word_label.shape, dtype=np.uint8)
                  dy = grad_e * dx
                  p = np.array(new_pp[-1]) + np.array([dx, dy, dx, dy])
                  cv2.line(
                      line_img,
                      (int(p[0]), int(p[1])),
                      (int(p[2]), int(p[3])),
                      1,
                      thickness=1,
                  )
                  if (
                      np.sum(np.logical_and(word_label, line_img)) == 0
                      or r + 2 * step_r >= max_r
                  ):
                      epp = p
                      isEppFound = True
              if isSppFound and isEppFound:
                  break
  
          # pass if boundary of polygon is not found
          if not (isSppFound and isEppFound):
              polys.append(None)
              continue
  
          # make final polygon
          poly = []
          poly.append(warpCoord(Minv, (spp[0], spp[1])))
          for p in new_pp:
              poly.append(warpCoord(Minv, (p[0], p[1])))
          poly.append(warpCoord(Minv, (epp[0], epp[1])))
          poly.append(warpCoord(Minv, (epp[2], epp[3])))
          for p in reversed(new_pp):
              poly.append(warpCoord(Minv, (p[2], p[3])))
          poly.append(warpCoord(Minv, (spp[2], spp[3])))
  
          # add to final result
          polys.append(np.array(poly))
  
      return polys
  
file_path: EasyOCR/easyocr/craft_utils.py
imports: import numpy
  import cv2
  import math
  from scipy.ndimage import label
label_desc: Use image node_id 3 for calling a global function with example usage: getPoly_core(boxes, labels, mapper, linkmap) and returns: polys