class_docstr: Generate local graphs for GCN to classify the neighbors of a pivot for
  `DRRG: Deep Relational Reasoning Graph Network for Arbitrary Shape Text
  Detection <[https://arxiv.org/abs/2003.07493]>`_.
  
  This code was partially adapted from
  https://github.com/GXYM/DRRG licensed under the MIT license.
  
  Args:
      k_at_hops (tuple(int)): The number of i-hop neighbors, i = 1, 2.
      num_adjacent_linkages (int): The number of linkages when constructing
          adjacent matrix.
      node_geo_feat_len (int): The length of embedded geometric feature
          vector of a text component.
      pooling_scale (float): The spatial scale of rotated RoI-Align.
      pooling_output_size (tuple(int)): The output size of rotated RoI-Align.
      local_graph_thr(float): The threshold for filtering out identical local
          graphs.
docstr: Generate graph convolution network input data.
  
  Args:
      node_feat_batch (List[Tensor]): The batched graph node features.
      node_label_batch (List[ndarray]): The batched text component
          labels.
      local_graph_batch (List[List[List[int]]]): The local graph node
          indices of image batch.
      knn_batch (List[List[List[int]]]): The knn graph node indices of
          image batch.
      sorted_dist_ind_batch (List[ndarray]): The node indices sorted
          according to the Euclidean distance.
  
  Returns:
      Tuple(local_graphs_node_feat, adjacent_matrices, pivots_knn_inds,
      gt_linkage):
  
      - local_graphs_node_feat (Tensor): The node features of graph.
      - adjacent_matrices (Tensor): The adjacent matrices of local
        graphs.
      - pivots_knn_inds (Tensor): The k-nearest neighbor indices in
          local graph.
      - gt_linkage (Tensor): The surpervision signal of GCN for linkage
          prediction.
docstr_tok: ["Generate","graph","convolution","network","input","data",".","Args",":","node_feat_batch","(","List","[","Tensor","]",")",":","The","batched","graph","node","features",".","node_label_batch","(","List","[","ndarray","]",")",":","The","batched","text","component","labels",".","local_graph_batch","(","List","[","List","[","List","[","int","]","]","]",")",":","The","local","graph","node","indices","of","image","batch",".","knn_batch","(","List","[","List","[","List","[","int","]","]","]",")",":","The","knn","graph","node","indices","of","image","batch",".","sorted_dist_ind_batch","(","List","[","ndarray","]",")",":","The","node","indices","sorted","according","to","the","Euclidean","distance",".","Returns",":","Tuple","(","local_graphs_node_feat",",","adjacent_matrices",",","pivots_knn_inds",",","gt_linkage",")",":","-","local_graphs_node_feat","(","Tensor",")",":","The","node","features","of","graph",".","-","adjacent_matrices","(","Tensor",")",":","The","adjacent","matrices","of","local","graphs",".","-","pivots_knn_inds","(","Tensor",")",":","The","k-nearest","neighbor","indices","in","local","graph",".","-","gt_linkage","(","Tensor",")",":","The","surpervision","signal","of","GCN","for","linkage","prediction","."]
code: def generate_gcn_input(
      self,
      node_feat_batch: List[Tensor],
      node_label_batch: List[ndarray],
      local_graph_batch: List[List[List[int]]],
      knn_batch: List[List[List[int]]],
      sorted_dist_ind_batch: List[ndarray],
  ) -> Tuple[Tensor, Tensor, Tensor, Tensor]:
      """Generate graph convolution network input data.
  
      Args:
          node_feat_batch (List[Tensor]): The batched graph node features.
          node_label_batch (List[ndarray]): The batched text component
              labels.
          local_graph_batch (List[List[List[int]]]): The local graph node
              indices of image batch.
          knn_batch (List[List[List[int]]]): The knn graph node indices of
              image batch.
          sorted_dist_ind_batch (List[ndarray]): The node indices sorted
              according to the Euclidean distance.
  
      Returns:
          Tuple(local_graphs_node_feat, adjacent_matrices, pivots_knn_inds,
          gt_linkage):
  
          - local_graphs_node_feat (Tensor): The node features of graph.
          - adjacent_matrices (Tensor): The adjacent matrices of local
            graphs.
          - pivots_knn_inds (Tensor): The k-nearest neighbor indices in
              local graph.
          - gt_linkage (Tensor): The surpervision signal of GCN for linkage
              prediction.
      """
      assert isinstance(node_feat_batch, list)
      assert isinstance(node_label_batch, list)
      assert isinstance(local_graph_batch, list)
      assert isinstance(knn_batch, list)
      assert isinstance(sorted_dist_ind_batch, list)
  
      num_max_nodes = max(
          len(pivot_local_graph)
          for pivot_local_graphs in local_graph_batch
          for pivot_local_graph in pivot_local_graphs
      )
  
      local_graphs_node_feat = []
      adjacent_matrices = []
      pivots_knn_inds = []
      pivots_gt_linkage = []
  
      for batch_ind, sorted_dist_inds in enumerate(
          sorted_dist_ind_batch
      ):
          node_feats = node_feat_batch[batch_ind]
          pivot_local_graphs = local_graph_batch[batch_ind]
          pivot_knns = knn_batch[batch_ind]
          node_labels = node_label_batch[batch_ind]
          device = node_feats.device
  
          for graph_ind, pivot_knn in enumerate(pivot_knns):
              pivot_local_graph = pivot_local_graphs[graph_ind]
              num_nodes = len(pivot_local_graph)
              pivot_ind = pivot_local_graph[0]
              node2ind_map = {
                  j: i for i, j in enumerate(pivot_local_graph)
              }
  
              knn_inds = torch.tensor(
                  [node2ind_map[i] for i in pivot_knn[1:]]
              )
              pivot_feats = node_feats[pivot_ind]
              normalized_feats = (
                  node_feats[pivot_local_graph] - pivot_feats
              )
  
              adjacent_matrix = np.zeros(
                  (num_nodes, num_nodes), dtype=np.float32
              )
              for node in pivot_local_graph:
                  neighbors = sorted_dist_inds[
                      node, 1 : self.num_adjacent_linkages + 1
                  ]
                  for neighbor in neighbors:
                      if neighbor in pivot_local_graph:
                          adjacent_matrix[
                              node2ind_map[node], node2ind_map[neighbor]
                          ] = 1
                          adjacent_matrix[
                              node2ind_map[neighbor], node2ind_map[node]
                          ] = 1
  
              adjacent_matrix = normalize_adjacent_matrix(
                  adjacent_matrix
              )
              pad_adjacent_matrix = torch.zeros(
                  (num_max_nodes, num_max_nodes),
                  dtype=torch.float,
                  device=device,
              )
              pad_adjacent_matrix[
                  :num_nodes, :num_nodes
              ] = torch.from_numpy(adjacent_matrix)
  
              pad_normalized_feats = torch.cat(
                  [
                      normalized_feats,
                      torch.zeros(
                          (
                              num_max_nodes - num_nodes,
                              normalized_feats.shape[1],
                          ),
                          dtype=torch.float,
                          device=device,
                      ),
                  ],
                  dim=0,
              )
  
              local_graph_labels = node_labels[pivot_local_graph]
              knn_labels = local_graph_labels[knn_inds]
              link_labels = (
                  (node_labels[pivot_ind] == knn_labels)
                  & (node_labels[pivot_ind] > 0)
              ).astype(np.int64)
              link_labels = torch.from_numpy(link_labels)
  
              local_graphs_node_feat.append(pad_normalized_feats)
              adjacent_matrices.append(pad_adjacent_matrix)
              pivots_knn_inds.append(knn_inds)
              pivots_gt_linkage.append(link_labels)
  
      local_graphs_node_feat = torch.stack(local_graphs_node_feat, 0)
      adjacent_matrices = torch.stack(adjacent_matrices, 0)
      pivots_knn_inds = torch.stack(pivots_knn_inds, 0)
      pivots_gt_linkage = torch.stack(pivots_gt_linkage, 0)
  
      return (
          local_graphs_node_feat,
          adjacent_matrices,
          pivots_knn_inds,
          pivots_gt_linkage,
      )
  
imports: from typing import Dict, List, Optional, Sequence, Tuple, Union
  import cv2
  import numpy
  import torch
  import torch.nn
  import torch.nn.functional
  from mmcv.ops import RoIAlignRotated
  from mmengine.model import BaseModule
  from numpy import ndarray
  from torch import Tensor
  from torch.nn import init
  from mmocr.models.textdet.heads import BaseTextDetHead
  from mmocr.registry import MODELS
  from mmocr.structures import TextDetDataSample
  from mmocr.utils import fill_hole
label_desc: Use image node_id 3 for calling the LocalGraphs obj's underlying member method code with example usage: obj.generate_gcn_input(node_feat_batch, node_label_batch, local_graph_batch, knn_batch, sorted_dist_ind_batch) and returns: local_graphs_node_feat,  adjacent_matrices,  pivots_knn_inds,  pivots_gt_linkage