text: import logging
  import glob
  # from tqdm import tqdm
  import numpy as np
  import torch
  import cv2
  # from skimage import io
  
  
  class FaceDetector(object):
      """An abstract class representing a face detector.
  
      Any other face detection implementation must subclass it. All subclasses
      must implement ``detect_from_image``, that return a list of detected
      bounding boxes. Optionally, for speed considerations detect from path is
      recommended.
      """
  
      def __init__(self, device, verbose):
          self.device = device
          self.verbose = verbose
  
          if verbose:
              if 'cpu' in device:
                  logger = logging.getLogger(__name__)
                  logger.warning("Detection running on CPU, this may be potentially slow.")
  
          if 'cpu' not in device and 'cuda' not in device:
              if verbose:
                  logger.error("Expected values for device are: {cpu, cuda} but got: %s", device)
              raise ValueError
  
      def detect_from_image(self, tensor_or_path):
          """Detects faces in a given image.
  
          This function detects the faces present in a provided BGR(usually)
          image. The input can be either the image itself or the path to it.
  
          Arguments:
              tensor_or_path {numpy.ndarray, torch.tensor or string} -- the path
              to an image or the image itself.
  
          Example::
  
              >>> path_to_image = 'data/image_01.jpg'
              ...   detected_faces = detect_from_image(path_to_image)
              [A list of bounding boxes (x1, y1, x2, y2)]
              >>> image = cv2.imread(path_to_image)
              ...   detected_faces = detect_from_image(image)
              [A list of bounding boxes (x1, y1, x2, y2)]
  
          """
          raise NotImplementedError
  
      def detect_from_directory(self, path, extensions=['.jpg', '.png'], recursive=False, show_progress_bar=True):
          """Detects faces from all the images present in a given directory.
  
          Arguments:
              path {string} -- a string containing a path that points to the folder containing the images
  
          Keyword Arguments:
              extensions {list} -- list of string containing the extensions to be
              consider in the following format: ``.extension_name`` (default:
              {['.jpg', '.png']}) recursive {bool} -- option wherever to scan the
              folder recursively (default: {False}) show_progress_bar {bool} --
              display a progressbar (default: {True})
  
          Example:
          >>> directory = 'data'
          ...   detected_faces = detect_from_directory(directory)
          {A dictionary of [lists containing bounding boxes(x1, y1, x2, y2)]}
  
          """
          if self.verbose:
              logger = logging.getLogger(__name__)
  
          if len(extensions) == 0:
              if self.verbose:
                  logger.error("Expected at list one extension, but none was received.")
              raise ValueError
  
          if self.verbose:
              logger.info("Constructing the list of images.")
          additional_pattern = '/**/*' if recursive else '/*'
          files = []
          for extension in extensions:
              files.extend(glob.glob(path + additional_pattern + extension, recursive=recursive))
  
          if self.verbose:
              logger.info("Finished searching for images. %s images found", len(files))
              logger.info("Preparing to run the detection.")
  
          predictions = {}
          for image_path in tqdm(files, disable=not show_progress_bar):
              if self.verbose:
                  logger.info("Running the face detector on image: %s", image_path)
              predictions[image_path] = self.detect_from_image(image_path)
  
          if self.verbose:
              logger.info("The detector was successfully run on all %s images", len(files))
  
          return predictions
  
      @property
      def reference_scale(self):
          raise NotImplementedError
  
      @property
      def reference_x_shift(self):
          raise NotImplementedError
  
      @property
      def reference_y_shift(self):
          raise NotImplementedError
  
      @staticmethod
      def tensor_or_path_to_ndarray(tensor_or_path, rgb=True):
          """Convert path (represented as a string) or torch.tensor to a numpy.ndarray
  
          Arguments:
              tensor_or_path {numpy.ndarray, torch.tensor or string} -- path to the image, or the image itself
          """
          if isinstance(tensor_or_path, str):
              return cv2.imread(tensor_or_path) if not rgb else io.imread(tensor_or_path)
          elif torch.is_tensor(tensor_or_path):
              # Call cpu in case its coming from cuda
              return tensor_or_path.cpu().numpy()[..., ::-1].copy() if not rgb else tensor_or_path.cpu().numpy()
          elif isinstance(tensor_or_path, np.ndarray):
              return tensor_or_path[..., ::-1].copy() if not rgb else tensor_or_path
          else:
              raise TypeError
  