              image = cv2.imread(filename)  # pylint: disable=no-member
          except TypeError:
              raise Exception("Error while reading image", filename)
  
          if self.mask_function or self.training_opts["warp_to_landmarks"]:
              src_pts = self.get_landmarks(filename, image, side)
          if self.mask_function:
              image = self.mask_function(src_pts, image, channels=4)
  
          image = self.processing.color_adjust(image)
 
</s> remove         if self.mask_function:
            image = self.mask_function(src_pts, image, channels=4)
 </s> add         if self.mask_class:
            image = self.mask_class(src_pts, image, channels=4).mask </s> remove             self.aligned["face"] = AlignerExtract().transform(
 </s> add             face = AlignerExtract().transform( </s> remove             if not skip:
                for face in faces:
                    image = converter.patch_image(image, face)
                filename = str(self.output_dir / Path(filename).name)
 </s> add     def load_model(self):
        """ Load the model requested for conversion """
        logger.debug("Loading Model")
        model_dir = get_folder(self.args.model_dir, make_folder=False)
        if not model_dir:
            logger.error("%s does not exist.", self.args.model_dir)
            exit(1)
        trainer = self.get_trainer(model_dir)
        model = PluginLoader.get_model(trainer)(model_dir, self.args.gpus, predict=True)
        logger.debug("Loaded Model")
        return model </s> remove                 if self.args.draw_transparent:
                    filename = "{}.png".format(os.path.splitext(filename)[0])
                    logger.trace("Set extension to png: `%s`", filename)
 </s> add     def get_trainer(self, model_dir):
        """ Return the trainer name if provided, or read from state file """
        if self.args.trainer:
            logger.debug("Trainer name provided: '%s'", self.args.trainer)
            return self.args.trainer

        statefile = [fname for fname in os.listdir(str(model_dir))
                     if fname.endswith("_state.json")]
        if len(statefile) != 1:
            logger.error("There should be 1 state file in your model folder. %s were found. "
                         "Specify a trainer with the '-t', '--trainer' option.")
            exit(1)
        statefile = os.path.join(str(model_dir), statefile[0])

        with open(statefile, "rb") as inp:
            state = self.serializer.unmarshal(inp.read().decode("utf-8"))
            trainer = state.get("name", None)

        if not trainer:
            logger.error("Trainer name could not be read from state file. "
                         "Specify a trainer with the '-t', '--trainer' option.")
            exit(1)
        logger.debug("Trainer from state file: '%s'", trainer)
        return trainer

    def predict_faces(self):
        """ Get detected faces from images """
        faces_seen = 0
        batch = list()
        while True:
            item = self.in_queue.get()
            if item != "EOF":
                logger.trace("Got from queue: '%s'", item["filename"])
                faces_count = len(item["detected_faces"])
                if faces_count != 0:
                    self.pre_process.do_actions(item)
                    self.faces_count += faces_count
                if faces_count > 1:
                    self.verify_output = True
                    logger.verbose("Found more than one face in an image! '%s'",
                                   os.path.basename(item["filename"]))

                self.load_aligned(item)

                faces_seen += faces_count
                batch.append(item)

            if faces_seen < self.batchsize and item != "EOF":
                logger.trace("Continuing. Current batchsize: %s", faces_seen)
                continue </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
        if self.mask_class or self.training_opts["warp_to_landmarks"]:
              image = cv2.imread(filename)  # pylint: disable=no-member
          except TypeError:
              raise Exception("Error while reading image", filename)
  
        if self.mask_class or self.training_opts["warp_to_landmarks"]:
              src_pts = self.get_landmarks(filename, image, side)
          if self.mask_function:
              image = self.mask_function(src_pts, image, channels=4)
  
          image = self.processing.color_adjust(image)
keep keep keep keep 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 
lib/training_data.py