Ejemplo n.º 1
0
    def apply_fixes(self, original, face, mask, landmarks):
        """ Apply fixes """
        #TODO copies aren't likey neccesary and will slow calc... used when isolating issues
        new_image = face[:, :, :3].copy()
        image_mask = mask[:, :, :3].copy()
        frame = original[:, :, :3].copy()

        #TODO - force default for args.sharpen_image to ensure it isn't None
        if self.args.sharpen_image is not None and self.args.sharpen_image.lower(
        ) != "none":
            new_image = self.sharpen(new_image, self.args.sharpen_image)

        if self.args.avg_color_adjust:
            new_image = self.color_adjust(new_image, frame, image_mask)

        if self.args.match_histogram:
            new_image = self.color_hist_match(new_image, frame, image_mask)

        if self.args.seamless_clone:
            blended = self.seamless_clone(new_image, frame, image_mask)
        else:
            foreground = new_image * image_mask
            background = frame * (1.0 - image_mask)
            blended = foreground + background

        np.clip(blended, 0.0, 255.0, out=blended)
        if self.args.draw_transparent:
            # Adding a 4th channel should happen after all other channel operations
            # Add mask as 4th channel for saving as alpha on supported output formats
            blended = dfl_full(landmarks, blended, channels=4)

        return np.rint(blended).astype('uint8')
Ejemplo n.º 2
0
 def dfl(self, **kwargs):
     """ DFaker Mask """
     logger.trace("Getting mask")
     dummy = np.zeros((kwargs["image_size"][1], kwargs["image_size"][0], 3), dtype='float32')
     mask = dfl_full(kwargs["landmarks"], dummy, channels=3)
     mask = self.intersect_rect(mask, **kwargs)
     return mask
Ejemplo n.º 3
0
    def patch_image(self, image, detected_face):
        """ Patch the image """
        logger.trace("Patching image")
        image = image.astype('float32')
        image_size = (image.shape[1], image.shape[0])
        coverage = int(self.training_coverage_ratio * self.training_size)
        padding = (self.training_size - coverage) // 2
        logger.trace("coverage: %s, padding: %s", coverage, padding)

        self.crop = slice(padding, self.training_size - padding)
        if not self.mask:  # Init the mask on first image
            self.mask = Mask(self.args.mask_type, self.training_size, padding,
                             self.crop)

        detected_face.load_aligned(image,
                                   size=self.training_size,
                                   align_eyes=False)
        new_image = self.get_new_image(image, detected_face, coverage,
                                       image_size)
        image_mask = self.get_image_mask(detected_face, image_size)

        if self.args.draw_transparent:
            new_image = dfl_full(
                detected_face.landmarks_as_xy, new_image, channels=4
            )  #Add mask as 4th channel for saving as alpha on supported output formats

            #This make sure that all the arrays match in size for later actions despite not actually using alpha in any way.
            image_mask = cv2.cvtColor(image_mask, cv2.COLOR_RGB2RGBA)
            image = cv2.cvtColor(image, cv2.COLOR_RGB2RGBA)

        patched_face = self.apply_fixes(image, new_image, image_mask,
                                        image_size)

        logger.trace("Patched image")
        return patched_face
Ejemplo n.º 4
0
    def apply_fixes(self, original, face, mask, image_size, landmarks):
        """ Apply fixes """

        new_image = face[:, :, :3].copy()
        image_mask = mask[:, :, :3].copy()
        frame = original[:, :, :3].copy()
        if self.args.sharpen_image is not None and self.args.sharpen_image.lower(
        ) != "none":
            np.clip(new_image, 0.0, 255.0, out=new_image)
            if self.args.sharpen_image == "box_filter":
                kernel = np.ones((3, 3)) * (-1)
                kernel[1, 1] = 9
                new_image = cv2.filter2D(new_image, -1, kernel)  # pylint: disable=no-member
            elif self.args.sharpen_image == "gaussian_filter":
                blur = cv2.GaussianBlur(new_image, (0, 0), 3.0)  # pylint: disable=no-member
                new_image = cv2.addWeighted(
                    new_image,  # pylint: disable=no-member
                    1.5,
                    blur,
                    -0.5,
                    0,
                    new_image)

        if self.args.avg_color_adjust:
            for _ in [0, 1]:
                np.clip(new_image, 0.0, 255.0, out=new_image)
                diff = frame - new_image
                avg_diff = np.sum(diff * image_mask, axis=(0, 1))
                adjustment = avg_diff / np.sum(image_mask, axis=(0, 1))
                new_image = new_image + adjustment

        if self.args.match_histogram:
            np.clip(new_image, 0.0, 255.0, out=new_image)
            new_image = self.color_hist_match(new_image, frame, image_mask)

        if self.args.seamless_clone:
            h, w, _ = frame.shape
            h = h // 2
            w = w // 2

            y_indices, x_indices, _ = np.nonzero(image_mask)
            y_crop = slice(np.min(y_indices), np.max(y_indices))
            x_crop = slice(np.min(x_indices), np.max(x_indices))
            y_center = int(
                np.rint((np.max(y_indices) + np.min(y_indices)) / 2) + h)
            x_center = int(
                np.rint((np.max(x_indices) + np.min(x_indices)) / 2) + w)
            '''
            # test with average of centroid rather than the h /2 , w/2 center
            y_center = int(np.rint(np.average(y_indices) + h)
            x_center = int(np.rint(np.average(x_indices) + w)
            '''

            insertion = np.rint(new_image[y_crop, x_crop, :]).astype('uint8')
            insertion_mask = image_mask[y_crop, x_crop, :]
            insertion_mask[insertion_mask != 0] = 255
            insertion_mask = insertion_mask.astype('uint8')

            prior = np.pad(frame, ((h, h), (w, w), (0, 0)),
                           'constant').astype('uint8')

            blended = cv2.seamlessClone(
                insertion,  # pylint: disable=no-member
                prior,
                insertion_mask,
                (x_center, y_center),
                cv2.NORMAL_CLONE)  # pylint: disable=no-member
            blended = blended[h:-h, w:-w]

        else:
            foreground = new_image * image_mask
            background = frame * (1.0 - image_mask)
            blended = foreground + background
        np.clip(blended, 0.0, 255.0, out=blended)
        if self.args.draw_transparent:
            # Adding a 4th channel should happen after all other channel operations
            # Add mask as 4th channel for saving as alpha on supported output formats
            blended = dfl_full(landmarks, blended, channels=4)

        return np.rint(blended).astype('uint8')