                       "landmarks: %s)",
                       self.x, self.w, self.y, self.h, self.landmarksXY)
  
      # <<< Aligned Face methods and properties >>> #
      def load_aligned(self, image, size=256, align_eyes=False):
          """ No need to load aligned information for all uses of this
              class, so only call this to load the information for easy
              reference to aligned properties for this face """
          logger.trace("Loading aligned face: (size: %s, align_eyes: %s)", size, align_eyes)
          padding = int(size * 0.1875)
 
</s> remove         logger.trace("Loading aligned face: (size: %s, align_eyes: %s)", size, align_eyes)
        padding = int(size * 0.1875)
 </s> add         logger.trace("Loading aligned face: (size: %s, align_eyes: %s, dtype: %s)",
                     size, align_eyes, dtype)
        padding = int(size * self.extract_ratio) // 2 </s> remove             self.aligned["face"] = AlignerExtract().transform(
 </s> add             face = AlignerExtract().transform( </s> remove                 cv2.imwrite(filename, image)  # pylint: disable=no-member
        except Exception as err:
            logger.error("Failed to convert image: '%s'. Reason: %s", filename, err)
            raise
 </s> add             if batch:
                detected_batch = [detected_face for item in batch
                                  for detected_face in item["detected_faces"]]
                feed_faces = self.compile_feed_faces(detected_batch)
                predicted = self.predict(feed_faces)

                self.queue_out_frames(batch, predicted)

            faces_seen = 0
            batch = list()
            if item == "EOF":
                logger.debug("Load queue complete")
                break
        self.out_queue.put("EOF")

    def load_aligned(self, item):
        """ Load the feed faces and reference output faces """
        logger.trace("Loading aligned faces: '%s'", item["filename"])
        for detected_face in item["detected_faces"]:
            detected_face.load_feed_face(item["image"],
                                         size=self.input_size,
                                         coverage_ratio=self.coverage_ratio,
                                         dtype="float32")
            if self.input_size == self.output_size:
                detected_face.reference = detected_face.feed
            else:
                detected_face.load_reference_face(item["image"],
                                                  size=self.output_size,
                                                  coverage_ratio=self.coverage_ratio,
                                                  dtype="float32")
        logger.trace("Loaded aligned faces: '%s'", item["filename"])

    @staticmethod
    def compile_feed_faces(detected_faces):
        """ Compile the faces for feeding into the predictor """
        logger.trace("Compiling feed face. Batchsize: %s", len(detected_faces))
        feed_faces = np.stack([detected_face.feed_face for detected_face in detected_faces])
        logger.trace("Compiled Feed faces. Shape: %s", feed_faces.shape)
        return feed_faces

    def predict(self, feed_faces):
        """ Perform inference on the feed """
        logger.trace("Predicting: Batchsize: %s", len(feed_faces))
        feed = [feed_faces]
        if self.has_predicted_mask:
            feed.append(np.repeat(self.input_mask, feed_faces.shape[0], axis=0))
        logger.trace("Input shape(s): %s", [item.shape for item in feed])

        predicted = self.predictor(feed)
        predicted = predicted if isinstance(predicted, list) else [predicted]
        logger.trace("Output shape(s): %s", [predict.shape for predict in predicted])

        # Compile masks into alpha channel or keep raw faces
        predicted = np.concatenate(predicted, axis=-1) if len(predicted) == 2 else predicted[0]
        predicted = predicted.astype("float32")

        logger.trace("Final shape: %s", predicted.shape)
        return predicted

    def queue_out_frames(self, batch, swapped_faces):
        """ Compile the batch back to original frames and put to out_queue """
        logger.trace("Queueing out batch. Batchsize: %s", len(batch))
        pointer = 0
        for item in batch:
            num_faces = len(item["detected_faces"])
            if num_faces == 0:
                item["swapped_faces"] = np.array(list())
            else:
                item["swapped_faces"] = swapped_faces[pointer:pointer + num_faces]

            logger.trace("Putting to queue. ('%s', detected_faces: %s, swapped_faces: %s)",
                         item["filename"], len(item["detected_faces"]),
                         item["swapped_faces"].shape[0])
            self.out_queue.put(item)
            pointer += num_faces
        logger.trace("Queued out batch. Batchsize: %s", len(batch)) </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
    def load_aligned(self, image, size=256, align_eyes=False, dtype=None):
                       "landmarks: %s)",
                       self.x, self.w, self.y, self.h, self.landmarksXY)
  
      # <<< Aligned Face methods and properties >>> #
    def load_aligned(self, image, size=256, align_eyes=False, dtype=None):
          """ No need to load aligned information for all uses of this
              class, so only call this to load the information for easy
              reference to aligned properties for this face """
          logger.trace("Loading aligned face: (size: %s, align_eyes: %s)", size, align_eyes)
          padding = int(size * 0.1875)
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/faces_detect.py