Files
faceswap/plugins/Convert_Adjust.py
T
Othniel Cundangan 810bd0bce7 Update GAN64 to v2 (#217)
* Clearer requirements for each platform

* Refactoring of old plugins (Model_Original + Extract_Align) + Cleanups

* Adding GAN128

* Update GAN to v2

* Create instance_normalization.py

* Fix decoder output

* Revert "Fix decoder output"

This reverts commit 3a8ecb8957.

* Fix convert

* Enable all options except perceptual_loss by default

* Disable instance norm

* Update Model.py

* Update Trainer.py

* Match GAN128 to shaoanlu's latest v2

* Add first_order to GAN128

* Disable `use_perceptual_loss`

* Fix call to `self.first_order`

* Switch to average loss in output

* Constrain average to last 100 iterations

* Fix math, constrain average to intervals of 100

* Fix math averaging again

* Remove math and simplify this damn averagin

* Add gan128 conversion

* Update convert.py

* Use non-warped images in masked preview

* Add K.set_learning_phase(1) to gan64

* Add K.set_learning_phase(1) to gan128

* Add missing keras import

* Use non-warped images in masked preview for gan128

* Exclude deleted faces from conversion

* --input-aligned-dir defaults to "{input_dir}/aligned"

* Simplify map operation

* port 'face_alignment' from PyTorch to Keras. It works x2 faster, but initialization takes 20secs.

2DFAN-4.h5 and mmod_human_face_detector.dat included in lib\FaceLandmarksExtractor

fixed dlib vs tensorflow conflict: dlib must do op first, then load keras model, otherwise CUDA OOM error

if face location not found by CNN, its try to find by HOG.

removed this:
-        if face.landmarks == None:
-            print("Warning! landmarks not found. Switching to crop!")
-            return cv2.resize(face.image, (size, size))
because DetectedFace always has landmarks

* Enabled masked converter for GAN models

* Histogram matching, cli option for perceptual loss

* Fix init() positional args error

* Add backwards compatibility for aligned filenames

* Fix masked converter

* Remove GAN converters
2018-03-09 19:43:24 -05:00

65 lines
2.4 KiB
Python

# Based on the original https://www.reddit.com/r/deepfakes/ code sample
# Adjust code made by https://github.com/yangchen8710
import cv2
import numpy
import os
class Convert(object):
def __init__(self, encoder, smooth_mask=True, avg_color_adjust=True, **kwargs):
self.encoder = encoder
self.use_smooth_mask = smooth_mask
self.use_avg_color_adjust = avg_color_adjust
def patch_image( self, original, face_detected, size ):
#assert image.shape == (256, 256, 3)
image = cv2.resize(face_detected.image, (256, 256))
crop = slice(48, 208)
face = image[crop, crop]
old_face = face.copy()
face = cv2.resize(face, (size, size))
face = numpy.expand_dims(face, 0)
new_face = self.encoder(face / 255.0)[0]
new_face = numpy.clip(new_face * 255, 0, 255).astype(image.dtype)
new_face = cv2.resize(new_face, (160, 160))
if self.use_avg_color_adjust:
self.adjust_avg_color(old_face,new_face)
if self.use_smooth_mask:
self.smooth_mask(old_face,new_face)
new_face = self.superpose(image, new_face, crop)
original[slice(face_detected.y, face_detected.y + face_detected.h), slice(face_detected.x, face_detected.x + face_detected.w)] = cv2.resize(new_face, (face_detected.w, face_detected.h))
return original
def adjust_avg_color(self,img_old,img_new):
w,h,c = img_new.shape
for i in range(img_new.shape[-1]):
old_avg = img_old[:, :, i].mean()
new_avg = img_new[:, :, i].mean()
diff_int = (int)(old_avg - new_avg)
for m in range(img_new.shape[0]):
for n in range(img_new.shape[1]):
temp = (img_new[m,n,i] + diff_int)
if temp < 0:
img_new[m,n,i] = 0
elif temp > 255:
img_new[m,n,i] = 255
else:
img_new[m,n,i] = temp
def smooth_mask(self,img_old,img_new):
w,h,c = img_new.shape
crop = slice(0,w)
mask = numpy.zeros_like(img_new)
mask[h//15:-h//15,w//15:-w//15,:] = 255
mask = cv2.GaussianBlur(mask,(15,15),10)
img_new[crop,crop] = mask/255*img_new + (1-mask/255)*img_old
def superpose(self,image, new_face, crop):
new_image = image.copy()
new_image[crop, crop] = new_face
return new_image