text: import cv2
  import numpy as np
  from typing import List, Tuple
  
  def read_img(path):
      return cv2.cvtColor(cv2.imread(path), cv2.COLOR_BGR2RGB)
  
  
  def clip_boxes(bboxes: List, img_h: int, img_w: int):
      if bboxes:
          bboxes = np.array(bboxes)
          bboxes[:, 0:4:2] = np.clip(bboxes[:, 0:4:2], 0, img_w)
          bboxes[:, 1:4:2] = np.clip(bboxes[:, 1:4:2], 0, img_h)
      return bboxes
  
  
  def resize_boxes(bboxes: List, out_stride: int):
      if bboxes:
          bboxes = np.array(bboxes)
          bboxes[:, 0:4] *= out_stride
      return bboxes
  
  
  def gaussian2D(shape: Tuple[int, int], sigma: float = 1.):
      m, n = [(ss - 1.) / 2. for ss in shape]
      y, x = np.ogrid[-m:m + 1, -n:n + 1]
  
      h = np.exp(-(x * x + y * y) / (2 * sigma * sigma))
      h[h < np.finfo(h.dtype).eps * h.max()] = 0
      return h
  
  
  def draw_gaussian(heatmap: np.array, center: List, radius: int, k: int = 1):
      diameter = 2 * radius + 1
      gaussian = gaussian2D((diameter, diameter), sigma=diameter / 6)
  
      x, y = center
      height, width = heatmap.shape[0:2]
  
      left, right = min(x, radius), min(width - x, radius + 1)
      top, bottom = min(y, radius), min(height - y, radius + 1)
  
      masked_heatmap = heatmap[y - top:y + bottom, x - left:x + right]
      masked_gaussian = gaussian[radius - top:radius + bottom, radius - left:radius + right]
      if min(masked_gaussian.shape) > 0 and min(masked_heatmap.shape) > 0:  # TODO debug
          np.maximum(masked_heatmap, masked_gaussian * k, out=masked_heatmap)
      return heatmap
  
  
  def gaussian_radius(det_size: List, min_overlap: float = 0.7):
      height, width = det_size
  
      a1 = 1
      b1 = (height + width)
      c1 = width * height * (1 - min_overlap) / (1 + min_overlap)
      sq1 = np.sqrt(b1 ** 2 - 4 * a1 * c1)
      r1 = (b1 + sq1) / 2
  
      a2 = 4
      b2 = 2 * (height + width)
      c2 = (1 - min_overlap) * width * height
      sq2 = np.sqrt(b2 ** 2 - 4 * a2 * c2)
      r2 = (b2 + sq2) / 2
  
      a3 = 4 * min_overlap
      b3 = -2 * min_overlap * (height + width)
      c3 = (min_overlap - 1) * width * height
      sq3 = np.sqrt(b3 ** 2 - 4 * a3 * c3)
      r3 = (b3 + sq3) / 2
      return min(r1, r2, r3)
  