Esempio n. 1
0
    def _load_disk_frames(self):
        """ Generator to load frames from a folder of images.

        Yields
        ------
        filename: str
            The filename of the current frame
        image: :class:`numpy.ndarray`
            A single frame
        """
        logger.debug("Input is separate Frames. Loading images")
        for filename in self._input_images:
            image = read_image(filename, raise_error=False)
            if image is None:
                continue
            yield filename, image
Esempio n. 2
0
    def sort_face(self):
        """ Sort by face similarity """
        input_dir = self.args.input_dir

        logger.info("Sorting by face similarity...")

        images = np.array(self.find_images(input_dir))
        preds = np.array([
            self.vgg_face.predict(read_image(img, raise_error=True))
            for img in tqdm(images, desc="loading", file=sys.stdout)
        ])
        logger.info(
            "Sorting. Depending on ths size of your dataset, this may take a few "
            "minutes...")
        indices = self.vgg_face.sorted_similarity(preds, method="ward")
        img_list = images[indices]
        return img_list
Esempio n. 3
0
 def image_size(self):
     """ Get the training set image size for storing in model data """
     image = read_image(self.images["a"][0], raise_error=True)
     size = image.shape[0]
     logger.debug("Training image size: %s", size)
     return size
Esempio n. 4
0
def update_legacy_png_header(filename, alignments):
    """ Update a legacy extracted face from pre v2.1 alignments by placing the alignment data for
    the face in the png exif header for the given filename with the given alignment data.

    If the given file is not a .png then a png is created and the original file is removed

    Parameters
    ----------
    filename: str
        The image file to update
    alignments: :class:`lib.align.alignments.Alignments`
        The alignments data the contains the information to store in the image header. This must be
        a v2.0 or less alignments file as later versions no longer store the face hash (unrequired)

    Returns
    -------
    dict
        The metadata that has been applied to the given image
    """
    if alignments.version > 2.0:
        raise FaceswapError(
            "The faces being passed in do not correspond to the given Alignments "
            "file. Please double check your sources and try again.")
    # Track hashes for multiple files with the same hash. Not the most robust but should be
    # effective enough
    folder = os.path.dirname(filename)
    if folder not in _HASHES_SEEN:
        _HASHES_SEEN[folder] = dict()
    hashes_seen = _HASHES_SEEN[folder]

    in_image = read_image(filename, raise_error=True)
    in_hash = sha1(in_image).hexdigest()
    hashes_seen[in_hash] = hashes_seen.get(in_hash, -1) + 1

    alignment = alignments.hashes_to_alignment.get(in_hash)
    if not alignment:
        logger.debug("Alignments not found for image: '%s'", filename)
        return None

    detected_face = DetectedFace()
    detected_face.from_alignment(alignment)
    # For dupe hash handling, make sure we get a different filename for repeat hashes
    src_fname, face_idx = list(
        alignments.hashes_to_frame[in_hash].items())[hashes_seen[in_hash]]
    orig_filename = "{}_{}.png".format(
        os.path.splitext(src_fname)[0], face_idx)
    meta = dict(alignments=detected_face.to_png_meta(),
                source=dict(alignments_version=alignments.version,
                            original_filename=orig_filename,
                            face_index=face_idx,
                            source_filename=src_fname,
                            source_is_video=False))  # Can't check so set false

    out_filename = f"{os.path.splitext(filename)[0]}.png"  # Make sure saved file is png
    out_image = encode_image(in_image, ".png", metadata=meta)

    with open(out_filename, "wb") as out_file:
        out_file.write(out_image)

    if filename != out_filename:  # Remove the old non-png:
        logger.debug("Removing replaced face with deprecated extension: '%s'",
                     filename)
        os.remove(filename)

    return meta