mirror of
https://github.com/iperov/DeepFaceLab.git
synced 2025-07-06 04:52:13 -07:00
fixed mask editor
added FacesetEnhancer 4.2.other) data_src util faceset enhance best GPU.bat 4.2.other) data_src util faceset enhance multi GPU.bat FacesetEnhancer greatly increases details in your source face set, same as Gigapixel enhancer, but in fully automatic mode. In OpenCL build it works on CPU only. Please consider a donation.
This commit is contained in:
parent
3be223a265
commit
d46fb5cfd3
6 changed files with 476 additions and 6 deletions
BIN
facelib/FaceEnhancer.h5
Normal file
BIN
facelib/FaceEnhancer.h5
Normal file
Binary file not shown.
154
facelib/FaceEnhancer.py
Normal file
154
facelib/FaceEnhancer.py
Normal file
|
@ -0,0 +1,154 @@
|
|||
import operator
|
||||
from pathlib import Path
|
||||
|
||||
import cv2
|
||||
import numpy as np
|
||||
|
||||
|
||||
|
||||
class FaceEnhancer(object):
|
||||
"""
|
||||
x4 face enhancer
|
||||
"""
|
||||
def __init__(self):
|
||||
from nnlib import nnlib
|
||||
exec( nnlib.import_all(), locals(), globals() )
|
||||
|
||||
model_path = Path(__file__).parent / "FaceEnhancer.h5"
|
||||
if not model_path.exists():
|
||||
return
|
||||
|
||||
bgr_inp = Input ( (192,192,3) )
|
||||
t_param_inp = Input ( (1,) )
|
||||
t_param1_inp = Input ( (1,) )
|
||||
x = Conv2D (64, 3, strides=1, padding='same' )(bgr_inp)
|
||||
|
||||
a = Dense (64, use_bias=False) ( t_param_inp )
|
||||
a = Reshape( (1,1,64) )(a)
|
||||
b = Dense (64, use_bias=False ) ( t_param1_inp )
|
||||
b = Reshape( (1,1,64) )(b)
|
||||
x = Add()([x,a,b])
|
||||
|
||||
x = LeakyReLU(0.1)(x)
|
||||
|
||||
x = LeakyReLU(0.1)(Conv2D (64, 3, strides=1, padding='same' )(x))
|
||||
x = e0 = LeakyReLU(0.1)(Conv2D (64, 3, strides=1, padding='same')(x))
|
||||
|
||||
x = AveragePooling2D()(x)
|
||||
x = LeakyReLU(0.1)(Conv2D (112, 3, strides=1, padding='same')(x))
|
||||
x = e1 = LeakyReLU(0.1)(Conv2D (112, 3, strides=1, padding='same')(x))
|
||||
|
||||
x = AveragePooling2D()(x)
|
||||
x = LeakyReLU(0.1)(Conv2D (192, 3, strides=1, padding='same')(x))
|
||||
x = e2 = LeakyReLU(0.1)(Conv2D (192, 3, strides=1, padding='same')(x))
|
||||
|
||||
x = AveragePooling2D()(x)
|
||||
x = LeakyReLU(0.1)(Conv2D (336, 3, strides=1, padding='same')(x))
|
||||
x = e3 = LeakyReLU(0.1)(Conv2D (336, 3, strides=1, padding='same')(x))
|
||||
|
||||
x = AveragePooling2D()(x)
|
||||
x = LeakyReLU(0.1)(Conv2D (512, 3, strides=1, padding='same')(x))
|
||||
x = e4 = LeakyReLU(0.1)(Conv2D (512, 3, strides=1, padding='same')(x))
|
||||
|
||||
x = AveragePooling2D()(x)
|
||||
x = LeakyReLU(0.1)(Conv2D (512, 3, strides=1, padding='same')(x))
|
||||
x = LeakyReLU(0.1)(Conv2D (512, 3, strides=1, padding='same')(x))
|
||||
x = LeakyReLU(0.1)(Conv2D (512, 3, strides=1, padding='same')(x))
|
||||
x = LeakyReLU(0.1)(Conv2D (512, 3, strides=1, padding='same')(x))
|
||||
|
||||
x = Concatenate()([ BilinearInterpolation()(x), e4 ])
|
||||
|
||||
x = LeakyReLU(0.1)(Conv2D (512, 3, strides=1, padding='same')(x))
|
||||
x = LeakyReLU(0.1)(Conv2D (512, 3, strides=1, padding='same')(x))
|
||||
|
||||
x = Concatenate()([ BilinearInterpolation()(x), e3 ])
|
||||
x = LeakyReLU(0.1)(Conv2D (512, 3, strides=1, padding='same')(x))
|
||||
x = LeakyReLU(0.1)(Conv2D (512, 3, strides=1, padding='same')(x))
|
||||
|
||||
x = Concatenate()([ BilinearInterpolation()(x), e2 ])
|
||||
x = LeakyReLU(0.1)(Conv2D (288, 3, strides=1, padding='same')(x))
|
||||
x = LeakyReLU(0.1)(Conv2D (288, 3, strides=1, padding='same')(x))
|
||||
|
||||
x = Concatenate()([ BilinearInterpolation()(x), e1 ])
|
||||
x = LeakyReLU(0.1)(Conv2D (160, 3, strides=1, padding='same')(x))
|
||||
x = LeakyReLU(0.1)(Conv2D (160, 3, strides=1, padding='same')(x))
|
||||
|
||||
x = Concatenate()([ BilinearInterpolation()(x), e0 ])
|
||||
x = LeakyReLU(0.1)(Conv2D (96, 3, strides=1, padding='same')(x))
|
||||
x = d0 = LeakyReLU(0.1)(Conv2D (96, 3, strides=1, padding='same')(x))
|
||||
|
||||
x = LeakyReLU(0.1)(Conv2D (48, 3, strides=1, padding='same')(x))
|
||||
|
||||
x = Conv2D (3, 3, strides=1, padding='same', activation='tanh')(x)
|
||||
out1x = Add()([bgr_inp, x])
|
||||
|
||||
x = d0
|
||||
x = LeakyReLU(0.1)(Conv2D (96, 3, strides=1, padding='same')(x))
|
||||
x = LeakyReLU(0.1)(Conv2D (96, 3, strides=1, padding='same')(x))
|
||||
x = d2x = BilinearInterpolation()(x)
|
||||
|
||||
x = LeakyReLU(0.1)(Conv2D (48, 3, strides=1, padding='same')(x))
|
||||
x = Conv2D (3, 3, strides=1, padding='same', activation='tanh')(x)
|
||||
|
||||
out2x = Add()([BilinearInterpolation()(out1x), x])
|
||||
|
||||
x = d2x
|
||||
x = LeakyReLU(0.1)(Conv2D (72, 3, strides=1, padding='same')(x))
|
||||
x = LeakyReLU(0.1)(Conv2D (72, 3, strides=1, padding='same')(x))
|
||||
x = d4x = BilinearInterpolation()(x)
|
||||
|
||||
x = LeakyReLU(0.1)(Conv2D (36, 3, strides=1, padding='same')(x))
|
||||
x = Conv2D (3, 3, strides=1, padding='same', activation='tanh')(x)
|
||||
out4x = Add()([BilinearInterpolation()(out2x), x ])
|
||||
|
||||
self.model = keras.models.Model ( [bgr_inp,t_param_inp,t_param1_inp], [out4x] )
|
||||
self.model.load_weights (str(model_path))
|
||||
|
||||
|
||||
def enhance (self, inp_img, is_tanh=False, preserve_size=True):
|
||||
if not is_tanh:
|
||||
inp_img = np.clip( inp_img * 2 -1, -1, 1 )
|
||||
|
||||
param = np.array([0.2])
|
||||
param1 = np.array([1.0])
|
||||
up_res = 4
|
||||
patch_size = 192
|
||||
patch_size_half = patch_size // 2
|
||||
|
||||
h,w,c = inp_img.shape
|
||||
|
||||
i_max = w-patch_size+1
|
||||
j_max = h-patch_size+1
|
||||
|
||||
final_img = np.zeros ( (h*up_res,w*up_res,c), dtype=np.float32 )
|
||||
final_img_div = np.zeros ( (h*up_res,w*up_res,1), dtype=np.float32 )
|
||||
|
||||
x = np.concatenate ( [ np.linspace (0,1,patch_size_half*up_res), np.linspace (1,0,patch_size_half*up_res) ] )
|
||||
x,y = np.meshgrid(x,x)
|
||||
patch_mask = (x*y)[...,None]
|
||||
|
||||
j=0
|
||||
while j < j_max:
|
||||
i = 0
|
||||
while i < i_max:
|
||||
patch_img = inp_img[j:j+patch_size, i:i+patch_size,:]
|
||||
x = self.model.predict( [ patch_img[None,...], param, param1 ] )[0]
|
||||
final_img [j*up_res:(j+patch_size)*up_res, i*up_res:(i+patch_size)*up_res,:] += x*patch_mask
|
||||
final_img_div[j*up_res:(j+patch_size)*up_res, i*up_res:(i+patch_size)*up_res,:] += patch_mask
|
||||
if i == i_max-1:
|
||||
break
|
||||
i = min( i+patch_size_half, i_max-1)
|
||||
if j == j_max-1:
|
||||
break
|
||||
j = min( j+patch_size_half, j_max-1)
|
||||
|
||||
final_img_div[final_img_div==0] = 1.0
|
||||
final_img /= final_img_div
|
||||
|
||||
if preserve_size:
|
||||
final_img = cv2.resize (final_img, (w,h), cv2.INTER_LANCZOS4)
|
||||
|
||||
if not is_tanh:
|
||||
final_img = np.clip( final_img/2+0.5, 0, 1 )
|
||||
|
||||
return final_img
|
|
@ -3,4 +3,5 @@ from .DLIBExtractor import DLIBExtractor
|
|||
from .MTCExtractor import MTCExtractor
|
||||
from .S3FDExtractor import S3FDExtractor
|
||||
from .FANExtractor import FANExtractor
|
||||
from .PoseEstimator import PoseEstimator
|
||||
from .PoseEstimator import PoseEstimator
|
||||
from .FaceEnhancer import FaceEnhancer
|
Loading…
Add table
Add a link
Reference in a new issue