class_docstr: Decoding predictions of TextSnake to instances. This was partially
  adapted from https://github.com/princewang1994/TextSnake.pytorch.
  
  Args:
      text_repr_type (str): The boundary encoding type 'poly' or 'quad'.
      min_text_region_confidence (float): The confidence threshold of text
          region in TextSnake.
      min_center_region_confidence (float): The confidence threshold of text
          center region in TextSnake.
      min_center_area (int): The minimal text center region area.
      disk_overlap_thr (float): The radius overlap threshold for merging
          disks.
      radius_shrink_ratio (float): The shrink ratio of ordered disks radii.
      rescale_fields (list[str], optional): The bbox/polygon field names to
          be rescaled. If None, no rescaling will be performed.
class_docstr_tok: ["Decoding","predictions","of","TextSnake","to","instances",".","This","was","partially","adapted","from","https",":","\/\/github.com\/princewang1994\/TextSnake.pytorch",".","Args",":","text_repr_type","(","str",")",":","The","boundary","encoding","type","'poly","'","or","'quad","'",".","min_text_region_confidence","(","float",")",":","The","confidence","threshold","of","text","region","in","TextSnake",".","min_center_region_confidence","(","float",")",":","The","confidence","threshold","of","text","center","region","in","TextSnake",".","min_center_area","(","int",")",":","The","minimal","text","center","region","area",".","disk_overlap_thr","(","float",")",":","The","radius","overlap","threshold","for","merging","disks",".","radius_shrink_ratio","(","float",")",":","The","shrink","ratio","of","ordered","disks","radii",".","rescale_fields","(","list","[","str","]",",","optional",")",":","The","bbox\/polygon","field","names","to","be","rescaled",".","If","None",",","no","rescaling","will","be","performed","."]
docstr: Args:
      pred_results (torch.Tensor): Prediction map with
          shape :math:`(C, H, W)`.
      data_sample (TextDetDataSample): Datasample of an image.
  
  Returns:
      list[list[float]]: The instance boundary and its confidence.
docstr_tok: ["Args",":","pred_results","(","torch.Tensor",")",":","Prediction","map","with","shape",":","math",":","`","(","C",",","H",",","W",")","`",".","data_sample","(","TextDetDataSample",")",":","Datasample","of","an","image",".","Returns",":","list","[","list","[","float","]","]",":","The","instance","boundary","and","its","confidence","."]
code: def get_text_instances(
      self, pred_results: torch.Tensor, data_sample: TextDetDataSample
  ) -> TextDetDataSample:
      """
      Args:
          pred_results (torch.Tensor): Prediction map with
              shape :math:`(C, H, W)`.
          data_sample (TextDetDataSample): Datasample of an image.
  
      Returns:
          list[list[float]]: The instance boundary and its confidence.
      """
      assert pred_results.dim() == 3
      data_sample.pred_instances = InstanceData()
      data_sample.pred_instances.polygons = []
      data_sample.pred_instances.scores = []
  
      pred_results[:2, :, :] = torch.sigmoid(pred_results[:2, :, :])
      pred_results = pred_results.detach().cpu().numpy()
  
      pred_text_score = pred_results[0]
      pred_text_mask = pred_text_score > self.min_text_region_confidence
      pred_center_score = pred_results[1] * pred_text_score
      pred_center_mask = (
          pred_center_score > self.min_center_region_confidence
      )
      pred_sin = pred_results[2]
      pred_cos = pred_results[3]
      pred_radius = pred_results[4]
      mask_sz = pred_text_mask.shape
  
      scale = np.sqrt(1.0 / (pred_sin**2 + pred_cos**2 + 1e-8))
      pred_sin = pred_sin * scale
      pred_cos = pred_cos * scale
  
      pred_center_mask = fill_hole(pred_center_mask).astype(np.uint8)
      center_contours, _ = cv2.findContours(
          pred_center_mask, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE
      )
  
      for contour in center_contours:
          if cv2.contourArea(contour) < self.min_center_area:
              continue
          instance_center_mask = np.zeros(mask_sz, dtype=np.uint8)
          cv2.drawContours(instance_center_mask, [contour], -1, 1, -1)
          skeleton = skeletonize(instance_center_mask)
          skeleton_yx = np.argwhere(skeleton > 0)
          y, x = skeleton_yx[:, 0], skeleton_yx[:, 1]
          cos = pred_cos[y, x].reshape((-1, 1))
          sin = pred_sin[y, x].reshape((-1, 1))
          radius = pred_radius[y, x].reshape((-1, 1))
  
          center_line_yx = self._centralize(
              skeleton_yx, cos, -sin, radius, instance_center_mask
          )
          y, x = center_line_yx[:, 0], center_line_yx[:, 1]
          radius = (
              pred_radius[y, x] * self.radius_shrink_ratio
          ).reshape((-1, 1))
          score = pred_center_score[y, x].reshape((-1, 1))
          instance_disks = np.hstack(
              [np.fliplr(center_line_yx), radius, score]
          )
          instance_disks = self._merge_disks(
              instance_disks, self.disk_overlap_thr
          )
  
          instance_mask = np.zeros(mask_sz, dtype=np.uint8)
          for x, y, radius, score in instance_disks:
              if radius > 1:
                  cv2.circle(
                      instance_mask,
                      (int(x), int(y)),
                      int(radius),
                      1,
                      -1,
                  )
          contours, _ = cv2.findContours(
              instance_mask, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE
          )
  
          score = np.sum(instance_mask * pred_text_score) / (
              np.sum(instance_mask) + 1e-8
          )
          if (
              len(contours) > 0
              and cv2.contourArea(contours[0]) > 0
              and contours[0].size > 8
          ):
              polygon = contours[0].flatten().tolist()
              data_sample.pred_instances.polygons.append(polygon)
              data_sample.pred_instances.scores.append(score)
  
      data_sample.pred_instances.scores = torch.FloatTensor(
          data_sample.pred_instances.scores
      )
  
      return data_sample
  
file_path: mmocr/mmocr/models/textdet/postprocessors/textsnake_postprocessor.py
imports: from typing import List, Sequence
  import cv2
  import numpy
  import torch
  from mmengine.structures import InstanceData
  from numpy.linalg import norm
  from skimage.morphology import skeletonize
  from mmocr.registry import MODELS
  from mmocr.structures import TextDetDataSample
  from mmocr.utils import fill_hole
  from .base import BaseTextDetPostProcessor
label_desc: Use image node_id 2 for calling the TextSnakePostprocessor obj's underlying member method code with example usage: obj.get_text_instances(pred_results, data_sample) and returns: data_sample