class_docstr: Implement TPS transform.
  
  This was partially adapted from https://github.com/ayumiymk/aster.pytorch
  
  Args:
      output_image_size (tuple[int, int]): The size of the output image.
          Defaults to (32, 128).
      num_control_points (int): The number of control points. Defaults to 20.
      margins (tuple[float, float]): The margins for control points to the
          top and down side of the image. Defaults to [0.05, 0.05].
class_docstr_tok: ["Implement","TPS","transform",".","This","was","partially","adapted","from","https",":","\/\/github.com\/ayumiymk\/aster.pytorch","Args",":","output_image_size","(","tuple","[","int",",","int","]",")",":","The","size","of","the","output","image",".","Defaults","to","(","32",",","128",")",".","num_control_points","(","int",")",":","The","number","of","control","points",".","Defaults","to","20.","margins","(","tuple","[","float",",","float","]",")",":","The","margins","for","control","points","to","the","top","and","down","side","of","the","image",".","Defaults","to","[","0.05",",","0.05","]","."]
docstr: Build the output control points.
  
  The output points will be fix at
  top and down side of the image.
  Args:
      num_control_points (Tensor): The number of control points.
      margins (Tuple[float, float]): The margins for control points to
          the top and down side of the image.
  Returns:
      Tensor: The output control points.
docstr_tok: ["Build","the","output","control","points",".","The","output","points","will","be","fix","at","top","and","down","side","of","the","image",".","Args",":","num_control_points","(","Tensor",")",":","The","number","of","control","points",".","margins","(","Tuple","[","float",",","float","]",")",":","The","margins","for","control","points","to","the","top","and","down","side","of","the","image",".","Returns",":","Tensor",":","The","output","control","points","."]
code: def _build_output_control_points(
      self,
      num_control_points: torch.Tensor,
      margins: Tuple[float, float],
  ) -> torch.Tensor:
      """Build the output control points.
  
      The output points will be fix at
      top and down side of the image.
      Args:
          num_control_points (Tensor): The number of control points.
          margins (Tuple[float, float]): The margins for control points to
              the top and down side of the image.
      Returns:
          Tensor: The output control points.
      """
      margin_x, margin_y = margins
      num_ctrl_pts_per_side = num_control_points // 2
      ctrl_pts_x = np.linspace(
          margin_x, 1.0 - margin_x, num_ctrl_pts_per_side
      )
      ctrl_pts_y_top = np.ones(num_ctrl_pts_per_side) * margin_y
      ctrl_pts_y_bottom = np.ones(num_ctrl_pts_per_side) * (
          1.0 - margin_y
      )
      ctrl_pts_top = np.stack([ctrl_pts_x, ctrl_pts_y_top], axis=1)
      ctrl_pts_bottom = np.stack(
          [ctrl_pts_x, ctrl_pts_y_bottom], axis=1
      )
      output_ctrl_pts_arr = np.concatenate(
          [ctrl_pts_top, ctrl_pts_bottom], axis=0
      )
      output_ctrl_pts = torch.Tensor(output_ctrl_pts_arr)
      return output_ctrl_pts
  
imports: import itertools
  from typing import Dict, List, Optional, Tuple, Union
  import numpy
  import torch
  import torch.nn
  import torch.nn.functional
  from mmcv.cnn import ConvModule
  from mmocr.registry import MODELS
  from .base import BasePreprocessor
label_desc: Use image node_id 5 for calling the TPStransform obj's underlying member method code with example usage: obj._build_output_control_points(num_control_points, margins) and returns: output_ctrl_pts