class_docstr: Implements a post processor for DBNet adapted from the implementation of `xuannianz
  <https://github.com/xuannianz/DifferentiableBinarization>`_.
  
  Args:
  ----
      unclip ratio: ratio used to unshrink polygons
      min_size_box: minimal length (pix) to keep a box
      max_candidates: maximum boxes to consider in a single page
      box_thresh: minimal objectness score to consider a box
      bin_thresh: threshold used to binzarized p_map at inference time
class_docstr_tok: ["Implements","a","post","processor","for","DBNet","adapted","from","the","implementation","of","`","xuannianz","<","https",":","\/\/github.com\/xuannianz\/DifferentiableBinarization",">","`","_",".","Args",":","--","--","unclip","ratio",":","ratio","used","to","unshrink","polygons","min_size_box",":","minimal","length","(","pix",")","to","keep","a","box","max_candidates",":","maximum","boxes","to","consider","in","a","single","page","box_thresh",":","minimal","objectness","score","to","consider","a","box","bin_thresh",":","threshold","used","to","binzarized","p_map","at","inference","time"]
docstr: Compute boxes from a bitmap/pred_map: find connected components then filter boxes
  
  Args:
  ----
      pred: Pred map from differentiable binarization output
      bitmap: Bitmap map computed from pred (binarized)
      angle_tol: Comparison tolerance of the angle with the median angle across the page
      ratio_tol: Under this limit aspect ratio, we cannot resolve the direction of the crop
  
  Returns:
  -------
      np tensor boxes for the bitmap, each box is a 5-element list
          containing x, y, w, h, score for the box
docstr_tok: ["Compute","boxes","from","a","bitmap\/pred_map",":","find","connected","components","then","filter","boxes","Args",":","--","--","pred",":","Pred","map","from","differentiable","binarization","output","bitmap",":","Bitmap","map","computed","from","pred","(","binarized",")","angle_tol",":","Comparison","tolerance","of","the","angle","with","the","median","angle","across","the","page","ratio_tol",":","Under","this","limit","aspect","ratio",",","we","can","not","resolve","the","direction","of","the","crop","Returns",":","--","--","--","-","np","tensor","boxes","for","the","bitmap",",","each","box","is","a","5-element","list","containing","x",",","y",",","w",",","h",",","score","for","the","box"]
code: def bitmap_to_boxes(
      self,
      pred: np.ndarray,
      bitmap: np.ndarray,
  ) -> np.ndarray:
      """Compute boxes from a bitmap/pred_map: find connected components then filter boxes
  
      Args:
      ----
          pred: Pred map from differentiable binarization output
          bitmap: Bitmap map computed from pred (binarized)
          angle_tol: Comparison tolerance of the angle with the median angle across the page
          ratio_tol: Under this limit aspect ratio, we cannot resolve the direction of the crop
  
      Returns:
      -------
          np tensor boxes for the bitmap, each box is a 5-element list
              containing x, y, w, h, score for the box
      """
      height, width = bitmap.shape[:2]
      min_size_box = 2
      boxes: List[Union[np.ndarray, List[float]]] = []
      # get contours from connected components on the bitmap
      contours, _ = cv2.findContours(
          bitmap.astype(np.uint8),
          cv2.RETR_EXTERNAL,
          cv2.CHAIN_APPROX_SIMPLE,
      )
      for contour in contours:
          # Check whether smallest enclosing bounding box is not too small
          if np.any(
              contour[:, 0].max(axis=0) - contour[:, 0].min(axis=0)
              < min_size_box
          ):
              continue
          # Compute objectness
          if self.assume_straight_pages:
              x, y, w, h = cv2.boundingRect(contour)
              points: np.ndarray = np.array(
                  [[x, y], [x, y + h], [x + w, y + h], [x + w, y]]
              )
              score = self.box_score(
                  pred, points, assume_straight_pages=True
              )
          else:
              score = self.box_score(
                  pred, contour, assume_straight_pages=False
              )
  
          if (
              score < self.box_thresh
          ):  # remove polygons with a weak objectness
              continue
  
          if self.assume_straight_pages:
              _box = self.polygon_to_box(points)
          else:
              _box = self.polygon_to_box(np.squeeze(contour))
  
          # Remove too small boxes
          if self.assume_straight_pages:
              if (
                  _box is None
                  or _box[2] < min_size_box
                  or _box[3] < min_size_box
              ):
                  continue
          elif (
              np.linalg.norm(_box[2, :] - _box[0, :], axis=-1)
              < min_size_box
          ):
              continue
  
          if self.assume_straight_pages:
              x, y, w, h = _box
              # compute relative polygon to get rid of img shape
              xmin, ymin, xmax, ymax = (
                  x / width,
                  y / height,
                  (x + w) / width,
                  (y + h) / height,
              )
              boxes.append([xmin, ymin, xmax, ymax, score])
          else:
              # compute relative box to get rid of img shape, in that case _box is a 4pt polygon
              if not isinstance(_box, np.ndarray) and _box.shape == (
                  4,
                  2,
              ):
                  raise AssertionError(
                      "When assume straight pages is false a box is a (4, 2) array (polygon)"
                  )
              _box[:, 0] /= width
              _box[:, 1] /= height
              boxes.append(_box)
  
      if not self.assume_straight_pages:
          return (
              np.clip(np.asarray(boxes), 0, 1)
              if len(boxes) > 0
              else np.zeros((0, 4, 2), dtype=pred.dtype)
          )
      else:
          return (
              np.clip(np.asarray(boxes), 0, 1)
              if len(boxes) > 0
              else np.zeros((0, 5), dtype=pred.dtype)
          )
  
file_path: doctr/doctr/models/detection/differentiable_binarization/base.py
imports: from typing import Dict, List, Tuple, Union
  import cv2
  import numpy
  import pyclipper
  from shapely.geometry import Polygon
  from ..core import DetectionPostProcessor
label_desc: Use image node_id 3 for calling the DBPostProcessor obj's underlying member method code with example usage: obj.bitmap_to_boxes(pred, bitmap) and returns: unknown, unknown