class_docstr: Implements an end-to-end OCR metric.
  
  The aggregated metrics are computed as follows:
  
  .. math::
      \forall (B, L) \in \mathcal{B}^N \times \mathcal{L}^N,
      \forall (\hat{B}, \hat{L}) \in \mathcal{B}^M \times \mathcal{L}^M, \\
      Recall(B, \hat{B}, L, \hat{L}) = \frac{1}{N} \sum\limits_{i=1}^N h_{B,L}(\hat{B}_i, \hat{L}_i) \\
      Precision(B, \hat{B}, L, \hat{L}) = \frac{1}{M} \sum\limits_{i=1}^M h_{B,L}(\hat{B}_i, \hat{L}_i) \\
      meanIoU(B, \hat{B}) = \frac{1}{M} \sum\limits_{i=1}^M \max\limits_{j \in [1, N]}  IoU(\hat{B}_i, B_j)
  
  with the function :math:`IoU(x, y)` being the Intersection over Union between bounding boxes :math:`x` and
  :math:`y`, and the function :math:`h_{B, L}` defined as:
  
  .. math::
      \forall (b, l) \in \mathcal{B} \times \mathcal{L},
      h_{B,L}(b, l) = \left\{
          \begin{array}{ll}
              1 & \mbox{if } b\mbox{ has been assigned to a given }B_j\mbox{ with an } \\
              & IoU \geq 0.5 \mbox{ and that for this assignment, } l = L_j\\
              0 & \mbox{otherwise.}
          \end{array}
      \right.
  
  where :math:`\mathcal{B}` is the set of possible bounding boxes,
  :math:`\mathcal{L}` is the set of possible character sequences,
  :math:`N` (number of ground truths) and :math:`M` (number of predictions) are strictly positive integers.
  
  >>> import numpy as np
  >>> from doctr.utils import OCRMetric
  >>> metric = OCRMetric(iou_thresh=0.5)
  >>> metric.update(np.asarray([[0, 0, 100, 100]]), np.asarray([[0, 0, 70, 70], [110, 95, 200, 150]]),
  >>>               ['hello'], ['hello', 'world'])
  >>> metric.summary()
  
  Args:
  ----
      iou_thresh: minimum IoU to consider a pair of prediction and ground truth as a match
      use_polygons: if set to True, predictions and targets will be expected to have rotated format
      mask_shape: if use_polygons is True, describes the spatial shape of the image used
      use_broadcasting: if use_polygons is True, use broadcasting for IoU computation by consuming more memory
class_docstr_tok: ["Implements","an","end-to-end","OCR","metric",".","The","aggregated","metrics","are","computed","as","follows",":","..","math",":",":","\\forall","(","B",",","L",")","\\in","\\mathcal","{","B","}","^N","\\times","\\mathcal","{","L","}","^N",",","\\forall","(","\\hat","{","B","}",",","\\hat","{","L","}",")","\\in","\\mathcal","{","B","}","^M","\\times","\\mathcal","{","L","}","^M",",","\\\\","Recall","(","B",",","\\hat","{","B","}",",","L",",","\\hat","{","L","}",")","=","\\frac","{","1","}","{","N","}","\\sum\\limits_","{","i=1","}","^N","h_","{","B",",","L","}","(","\\hat","{","B","}","_i",",","\\hat","{","L","}","_i",")","\\\\","Precision","(","B",",","\\hat","{","B","}",",","L",",","\\hat","{","L","}",")","=","\\frac","{","1","}","{","M","}","\\sum\\limits_","{","i=1","}","^M","h_","{","B",",","L","}","(","\\hat","{","B","}","_i",",","\\hat","{","L","}","_i",")","\\\\","meanIoU","(","B",",","\\hat","{","B","}",")","=","\\frac","{","1","}","{","M","}","\\sum\\limits_","{","i=1","}","^M","\\max\\limits_","{","j","\\in","[","1",",","N","]","}","IoU","(","\\hat","{","B","}","_i",",","B_j",")","with","the","function",":","math",":","`","IoU","(","x",",","y",")","`","being","the","Intersection","over","Union","between","bounding","boxes",":","math",":","`","x","`","and",":","math",":","`","y","`",",","and","the","function",":","math",":","`","h_","{","B",",","L","}","`","defined","as",":","..","math",":",":","\\forall","(","b",",","l",")","\\in","\\mathcal","{","B","}","\\times","\\mathcal","{","L","}",",","h_","{","B",",","L","}","(","b",",","l",")","=","\\left\\","{","\\begin","{","array","}","{","ll","}","1","&","\\mbox","{","if","}","b\\mbox","{","has","been","assigned","to","a","given","}","B_j\\mbox","{","with","an","}","\\\\","&","IoU","\\geq","0.5","\\mbox","{","and","that","for","this","assignment",",","}","l","=","L_j\\\\","0","&","\\mbox","{","otherwise",".","}","\\end","{","array","}","\\right",".","where",":","math",":","`","\\mathcal","{","B","}","`","is","the","set","of","possible","bounding","boxes",",",":","math",":","`","\\mathcal","{","L","}","`","is","the","set","of","possible","character","sequences",",",":","math",":","`","N","`","(","number","of","ground","truths",")","and",":","math",":","`","M","`","(","number","of","predictions",")","are","strictly","positive","integers",".",">",">",">","import","numpy","as","np",">",">",">","from","doctr.utils","import","OCRMetric",">",">",">","metric","=","OCRMetric","(","iou_thresh=0.5",")",">",">",">","metric.update","(","np.asarray","(","[","[","0",",","0",",","100",",","100","]","]",")",",","np.asarray","(","[","[","0",",","0",",","70",",","70","]",",","[","110",",","95",",","200",",","150","]","]",")",",",">",">",">","[","'hello","'","]",",","[","'hello","'",",","'world","'","]",")",">",">",">","metric.summary","(",")","Args",":","--","--","iou_thresh",":","minimum","IoU","to","consider","a","pair","of","prediction","and","ground","truth","as","a","match","use_polygons",":","if","set","to","True",",","predictions","and","targets","will","be","expected","to","have","rotated","format","mask_shape",":","if","use_polygons","is","True",",","describes","the","spatial","shape","of","the","image","used","use_broadcasting",":","if","use_polygons","is","True",",","use","broadcasting","for","IoU","computation","by","consuming","more","memory"]
docstr: Computes the aggregated metrics
  
  Returns
  -------
      a tuple with the recall & precision for each string comparison and the mean IoU
docstr_tok: ["Computes","the","aggregated","metrics","Returns","--","--","--","-","a","tuple","with","the","recall","&","precision","for","each","string","comparison","and","the","mean","IoU"]
code: def summary(
      self,
  ) -> Tuple[
      Dict[str, Optional[float]],
      Dict[str, Optional[float]],
      Optional[float],
  ]:
      """Computes the aggregated metrics
  
      Returns
      -------
          a tuple with the recall & precision for each string comparison and the mean IoU
      """
      # Recall
      recall = dict(
          raw=self.raw_matches / self.num_gts
          if self.num_gts > 0
          else None,
          caseless=self.caseless_matches / self.num_gts
          if self.num_gts > 0
          else None,
          unidecode=self.unidecode_matches / self.num_gts
          if self.num_gts > 0
          else None,
          unicase=self.unicase_matches / self.num_gts
          if self.num_gts > 0
          else None,
      )
  
      # Precision
      precision = dict(
          raw=self.raw_matches / self.num_preds
          if self.num_preds > 0
          else None,
          caseless=self.caseless_matches / self.num_preds
          if self.num_preds > 0
          else None,
          unidecode=self.unidecode_matches / self.num_preds
          if self.num_preds > 0
          else None,
          unicase=self.unicase_matches / self.num_preds
          if self.num_preds > 0
          else None,
      )
  
      # mean IoU (overall detected boxes)
      mean_iou = (
          self.tot_iou / self.num_preds if self.num_preds > 0 else None
      )
  
      return recall, precision, mean_iou
  
imports: from typing import Dict, List, Optional, Tuple
  import cv2
  import numpy
  from scipy.optimize import linear_sum_assignment
  from unidecode import unidecode
label_desc: Use image node_id 3 for calling the OCRMetric obj's underlying member method code with example usage: obj.summary() and returns: recall,  precision,  mean_iou