text: import warnings
  
  import mmcv
  import numpy as np
  import pycocotools.mask as maskUtils
  import torch
  from mmcv.runner import load_checkpoint
  
  from mmdet.core import get_classes
  from mmdet.datasets import to_tensor
  from mmdet.datasets.transforms import ImageTransform
  from mmdet.models import build_detector
  
  
  def init_detector(config, checkpoint=None, device='cuda:0'):
      """Initialize a detector from config file.
  
      Args:
          config (str or :obj:`mmcv.Config`): Config file path or the config
              object.
          checkpoint (str, optional): Checkpoint path. If left as None, the model
              will not load any weights.
  
      Returns:
          nn.Module: The constructed detector.
      """
      if isinstance(config, str):
          config = mmcv.Config.fromfile(config)
      elif not isinstance(config, mmcv.Config):
          raise TypeError('config must be a filename or Config object, '
                          'but got {}'.format(type(config)))
      config.model.pretrained = None
      model = build_detector(config.model, test_cfg=config.test_cfg)
      if checkpoint is not None:
          checkpoint = load_checkpoint(model, checkpoint)
          if 'CLASSES' in checkpoint['meta']:
              model.CLASSES = checkpoint['meta']['classes']
          else:
              warnings.warn('Class names are not saved in the checkpoint\'s '
                            'meta data, use COCO classes by default.')
              model.CLASSES = get_classes('coco')
      model.cfg = config  # save the config in the model for convenience
      model.to(device)
      model.eval()
      return model
  
  
  def inference_detector(model, imgs):
      """Inference image(s) with the detector.
  
      Args:
          model (nn.Module): The loaded detector.
          imgs (str/ndarray or list[str/ndarray]): Either image files or loaded
              images.
  
      Returns:
          If imgs is a str, a generator will be returned, otherwise return the
          detection results directly.
      """
      cfg = model.cfg
      img_transform = ImageTransform(
          size_divisor=cfg.data.test.size_divisor, **cfg.img_norm_cfg)
  
      device = next(model.parameters()).device  # model device
      if not isinstance(imgs, list):
          return _inference_single(model, imgs, img_transform, device)
      else:
          return _inference_generator(model, imgs, img_transform, device)
  
  
  def _prepare_data(img, img_transform, cfg, device):
      ori_shape = img.shape
      img, img_shape, pad_shape, scale_factor = img_transform(
          img,
          scale=cfg.data.test.img_scale,
          keep_ratio=cfg.data.test.get('resize_keep_ratio', True))
      img = to_tensor(img).to(device).unsqueeze(0)
      img_meta = [
          dict(
              ori_shape=ori_shape,
              img_shape=img_shape,
              pad_shape=pad_shape,
              scale_factor=scale_factor,
              flip=False)
      ]
      return dict(img=[img], img_meta=[img_meta])
  
  
  def _inference_single(model, img, img_transform, device):
      img = mmcv.imread(img)
      data = _prepare_data(img, img_transform, model.cfg, device)
      with torch.no_grad():
          result = model(return_loss=False, rescale=True, **data)
      return result
  
  
  def _inference_generator(model, imgs, img_transform, device):
      for img in imgs:
          yield _inference_single(model, img, img_transform, device)
  
  
  # TODO: merge this method with the one in BaseDetector
  def show_result(img, result, class_names, score_thr=0.3, out_file=None):
      """Visualize the detection results on the image.
  
      Args:
          img (str or np.ndarray): Image filename or loaded image.
          result (tuple[list] or list): The detection result, can be either
              (bbox, segm) or just bbox.
          class_names (list[str] or tuple[str]): A list of class names.
          score_thr (float): The threshold to visualize the bboxes and masks.
          out_file (str, optional): If specified, the visualization result will
              be written to the out file instead of shown in a window.
      """
      assert isinstance(class_names, (tuple, list))
      img = mmcv.imread(img)
      if isinstance(result, tuple):
          bbox_result, segm_result = result
      else:
          bbox_result, segm_result = result, None
      bboxes = np.vstack(bbox_result)
      # draw segmentation masks
      if segm_result is not None:
          segms = mmcv.concat_list(segm_result)
          inds = np.where(bboxes[:, -1] > score_thr)[0]
          for i in inds:
              color_mask = np.random.randint(
                  0, 256, (1, 3), dtype=np.uint8)
              mask = maskUtils.decode(segms[i]).astype(np.bool)
              img[mask] = img[mask] * 0.5 + color_mask * 0.5
      # draw bounding boxes
      labels = [
          np.full(bbox.shape[0], i, dtype=np.int32)
          for i, bbox in enumerate(bbox_result)
      ]
      labels = np.concatenate(labels)
      mmcv.imshow_det_bboxes(
          img.copy(),
          bboxes,
          labels,
          class_names=class_names,
          score_thr=score_thr,
          show=out_file is None,
          out_file=out_file)
  