code: def print_recall_summary(
      recalls,
      proposal_nums,
      iou_thrs,
      row_idxs=None,
      col_idxs=None,
      logger=None,
  ):
      """Print recalls in a table.
  
      Args:
          recalls (ndarray): calculated from `bbox_recalls`
          proposal_nums (ndarray or list): top N proposals
          iou_thrs (ndarray or list): iou thresholds
          row_idxs (ndarray): which rows(proposal nums) to print
          col_idxs (ndarray): which cols(iou thresholds) to print
          logger (logging.Logger | str | None): The way to print the recall
              summary. See `mmengine.logging.print_log()` for details.
              Default: None.
      """
      proposal_nums = np.array(proposal_nums, dtype=np.int32)
      iou_thrs = np.array(iou_thrs)
      if row_idxs is None:
          row_idxs = np.arange(proposal_nums.size)
      if col_idxs is None:
          col_idxs = np.arange(iou_thrs.size)
      row_header = [""] + iou_thrs[col_idxs].tolist()
      table_data = [row_header]
      for i, num in enumerate(proposal_nums[row_idxs]):
          row = [
              f"{val:.3f}"
              for val in recalls[row_idxs[i], col_idxs].tolist()
          ]
          row.insert(0, num)
          table_data.append(row)
      table = AsciiTable(table_data)
      print_log("\n" + table.table, logger=logger)
  
file_path: mmdetection/mmdet/evaluation/functional/recall.py
imports: from collections.abc import Sequence
  import numpy
  from mmengine.logging import print_log
  from terminaltables import AsciiTable
  from .bbox_overlaps import bbox_overlaps
label_desc: Use image node_id 4 for calling a global function with example usage: print_recall_summary(recalls, proposal_nums, iou_thrs, row_idxs, col_idxs, logger) without return types