          mod = ".".join(("plugins", attr, name))
          module = import_module(mod)
          return getattr(module, ttl)
  
      @staticmethod
      def get_available_models():
          """ Return a list of available models """
          modelpath = os.path.join(os.path.dirname(__file__), "train", "model")
          models = sorted(item.name.replace(".py", "").replace("_", "-")
                          for item in os.scandir(modelpath)
                          if not item.name.startswith("_")
                          and item.name.endswith(".py"))
          return models
  
      @staticmethod
      def get_available_converters():
          """ Return a list of available converters """
          converter_path = os.path.join(os.path.dirname(__file__), "convert")
          converters = sorted(item.name.replace(".py", "").replace("_", "-")
                              for item in os.scandir(converter_path)
                              if not item.name.startswith("_")
                              and item.name.endswith(".py"))
          return converters
  
      @staticmethod
      def get_available_extractors(extractor_type):
          """ Return a list of available models """
          extractpath = os.path.join(os.path.dirname(__file__),
                                     "extract",
 
</s> remove def dfaker(landmarks, face, channels=4):
    """ Dfaker model mask
        Embeds the mask into the face alpha channel

        channels: 1, 3 or 4:
                1 - Return a single channel mask
                3 - Return a 3 channel mask
                4 - Return the original image with the mask in the alpha channel
        """
    padding = int(face.shape[0] * 0.1875)
    coverage = face.shape[0] - (padding * 2)
    logger.trace("face_shape: %s, coverage: %s, landmarks: %s", face.shape, coverage, landmarks)

    mat = umeyama(landmarks[17:], True)[0:2]
    mat = mat.reshape(-1).reshape(2, 3)
    mat = mat * coverage
    mat[:, 2] += padding

    mask = np.zeros(face.shape[0:2] + (1, ), dtype=np.float32)
    hull = cv2.convexHull(landmarks).reshape(1, -1, 2)  # pylint: disable=no-member
    hull = cv2.transform(hull, mat).reshape(-1, 2)  # pylint: disable=no-member
    cv2.fillConvexPoly(mask, hull, 255.)  # pylint: disable=no-member

    kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (15, 15))  # pylint: disable=no-member
    mask = cv2.dilate(mask, kernel, borderType=cv2.BORDER_REFLECT)  # pylint: disable=no-member
    mask = np.expand_dims(mask, axis=-1)

    return merge_mask(face, mask, channels)


def dfl_full(landmarks, face, channels=4):
    """ DFL facial mask

        channels: 1, 3 or 4:
            1 - Return a single channel mask
            3 - Return a 3 channel mask
            4 - Return the original image with the mask in the alpha channel
        """
    logger.trace("face_shape: %s, landmarks: %s", face.shape, landmarks)
    mask = np.zeros(face.shape[0:2] + (1, ), dtype=np.float32)

    nose_ridge = (landmarks[27:31], landmarks[33:34])
    jaw = (landmarks[0:17], landmarks[48:68], landmarks[0:1],
           landmarks[8:9], landmarks[16:17])
    eyes = (landmarks[17:27], landmarks[0:1], landmarks[27:28],
            landmarks[16:17], landmarks[33:34])
    parts = [jaw, nose_ridge, eyes]
 </s> add def get_available_masks():
    """ Return a list of the available masks for cli """
    masks = sorted([name for name, obj in inspect.getmembers(sys.modules[__name__])
                    if inspect.isclass(obj) and name != "Mask"])
    masks.append("none")
    logger.debug(masks)
    return masks </s> remove         for item in batch.iterator():
            self.convert(converter, item)
 </s> add     @property
    def draw_transparent(self):
        """ Draw transparent is an image writer only parameter.
            Return the value here for easy access for predictor """
        return self.writer.config.get("draw_transparent", False)

    @property
    def pre_encode(self):
        """ Return the writer's pre-encoder """
        dummy = np.zeros((20, 20, 3)).astype("uint8")
        test = self.writer.pre_encode(dummy)
        retval = None if test is None else self.writer.pre_encode
        logger.debug("Writer pre_encode function: %s", retval)
        return retval

    @property
    def total_count(self):
        """ Return the total number of frames to be converted """
        if self.frame_ranges and not self.args.keep_unchanged:
            retval = sum([fr[1] - fr[0] for fr in self.frame_ranges])
        else:
            retval = self.images.images_found
        logger.debug(retval)
        return retval

    # Initalization
    def get_writer(self):
        """ Return the writer plugin """
        args = [self.args.output_dir]
        if self.args.writer in ("ffmpeg", "gif"):
            args.append(self.total_count)
        if self.args.writer == "ffmpeg":
            if self.images.is_video:
                args.append(self.args.input_dir)
            else:
                args.append(self.args.reference_video)
        logger.debug("Writer args: %s", args)
        return PluginLoader.get_converter("writer", self.args.writer)(*args)
          mod = ".".join(("plugins", attr, name))
          module = import_module(mod)
          return getattr(module, ttl)
  




















      @staticmethod
      def get_available_extractors(extractor_type):
          """ Return a list of available models """
          extractpath = os.path.join(os.path.dirname(__file__),
                                     "extract",
keep keep keep keep replace replace replace replace replace replace replace replace replace replace replace replace replace replace replace replace replace replace replace replace keep keep keep keep keep
 Convert refactor (#703)

* Separate predict and implement pool

* Add check and raise error to multithreading

Box functions to config. Add crop box option.

* All masks to mask module. Refactor convert masks

Predicted mask passed from model. Cli update

* Intesect box with mask and fixes

* Use raw NN output for convert

Use raw mask for face adjustments. Split adjustments to pre and post warp

* Separate out adjustments. Add unmask sharpen

* Set sensible defaults. Pre PR Testing

* Fix queue sizes. Move masked.py to lib

* Fix Skip Frames. Fix GUI Config popup

* Sensible queue limits. Add a less resource intensive single processing mode

* Fix predicted mask. Amend smooth box defaults

* Deterministic ordering for video output

* Video to Video convert implemented

* Fixups

- Remove defaults from folders across all stages
- Move match-hist and aca into color adjustments selectable
- Handle crashes properly for pooled processes
- Fix output directory does not exist error when creating a new output folder
- Force output to frames if input is not a video

* Add Color Transfer adjustment method

Wrap info text in GUI plugin configure popup

* Refactor image adjustments. Easier to create plugins

Start implementing config options for video encoding

* Add video encoding config options

Allow video encoding for frames input (must pass in a reference video)
Move video and image output writers to plugins

* Image writers config options

Move scaling to cli
Move draw_transparent to images config
Add config options for cv2 writer
Add Pillow image writer

* Add gif filetype to Pillow. Fix draw transparent for Pillow

* Add Animated GIF writer

standardize opencv/pillow defaults

* [speedup] Pre-encode supported writers in the convert pool (opencv, pillow)

Move scaling to convert pool
Remove dfaker mask

* Fix default writer

* Bugfixes

* Better custom argparse formatting 
plugins/plugin_loader.py