This commit is contained in:
yuyuyzl committed 2022-07-28 01:22:39 +08:00
1 parent 8b291db30b
commit 2b1277f163
4 files changed
+166 -103

No files matched your search

+2 -1
View File
@@ -12,12 +12,13 @@ def convert_to_byte(size):
parser = argparse.ArgumentParser()
parser.add_argument('--debug', action='store_true')
parser.add_argument('--eyebrow', action='store_true')
parser.add_argument('--extend_movement', type=float)
parser.add_argument('--input', type=str, default='cam')
parser.add_argument('--character', type=str, default='y')
parser.add_argument('--output_dir', type=str)
parser.add_argument('--output_webcam', type=str)
parser.add_argument('--output_size', type=str, default='256x256')
parser.add_argument('--output_size', type=str, default='512x512')
parser.add_argument('--model', type=str, default='standard_float')
parser.add_argument('--debug_input', action='store_true')
parser.add_argument('--mouse_input', type=str)
+7
View File
@@ -15,6 +15,7 @@ default_arg={
'is_anime4k': False,
'is_alpha_split': False,
'is_bongo': False,
'is_eyebrow': False,
'cache_simplify': 1,
'cache_size': 1,
'model_type': 0,
@@ -89,6 +90,9 @@ ttk.Radiobutton(launcher, text='4GB+2GB', value=4, variable=cache_size).pack(fil
ttk.Radiobutton(launcher, text='8GB+4GB', value=5, variable=cache_size).pack(fill='x', expand=True)
ttk.Label(launcher, text="Extra Options").pack(fill='x', expand=True)
is_eyebrow = tk.BooleanVar(value=args['is_eyebrow'])
ttk.Checkbutton(launcher, text='Eyebrow (iFM Only)', variable=is_eyebrow).pack(fill='x', expand=True)
is_extend_movement = tk.BooleanVar(value=args['is_extend_movement'])
ttk.Checkbutton(launcher, text='Extend Movement', variable=is_extend_movement).pack(fill='x', expand=True)
@@ -120,6 +124,7 @@ def launch():
'is_anime4k': is_anime4k.get(),
'is_alpha_split': is_alpha_split.get(),
'is_bongo': is_bongo.get(),
'is_eyebrow': is_eyebrow.get(),
'cache_simplify': cache_simplify.get(),
'cache_size': cache_size.get(),
'model_type': model_type.get(),
@@ -168,6 +173,8 @@ def launch():
run_args.append('1')
if args['is_bongo']:
run_args.append('--bongo')
if args['is_eyebrow']:
run_args.append('--eyebrow')
if args['cache_simplify'] is not None:
run_args.append('--simplify')
run_args.append(str(args['cache_simplify']))
+69 -57
View File
@@ -231,10 +231,12 @@ class ModelClientProcess(Process):
print("Pretrained Model Loaded")
eyebrow_vector = torch.empty(1, 12,dtype=torch.half if args.model.endswith('half') else torch.float)
mouth_eye_vector = torch.empty(1, 27,dtype=torch.half if args.model.endswith('half') else torch.float)
pose_vector = torch.empty(1, 6,dtype=torch.half if args.model.endswith('half') else torch.float)
input_image = self.input_image.to(device)
eyebrow_vector = eyebrow_vector.to(device)
mouth_eye_vector = mouth_eye_vector.to(device)
pose_vector = pose_vector.to(device)
@@ -274,29 +276,29 @@ class ModelClientProcess(Process):
simplify_arr[ifm_converter.head_y_index] = 100
simplify_arr[ifm_converter.eye_surprised_left_index] = 10
simplify_arr[ifm_converter.eye_surprised_right_index] = 10
model_input[ifm_converter.eye_wink_left_index - 12] += model_input[
ifm_converter.eye_happy_wink_left_index - 12]
model_input[ifm_converter.eye_happy_wink_left_index - 12] = model_input[
ifm_converter.eye_wink_left_index - 12] / 2
model_input[ifm_converter.eye_wink_left_index - 12] = model_input[
ifm_converter.eye_wink_left_index - 12] / 2
model_input[ifm_converter.eye_wink_right_index - 12] += model_input[
ifm_converter.eye_happy_wink_right_index - 12]
model_input[ifm_converter.eye_happy_wink_right_index - 12] = model_input[
ifm_converter.eye_wink_right_index - 12] / 2
model_input[ifm_converter.eye_wink_right_index - 12] = model_input[
ifm_converter.eye_wink_right_index - 12] / 2
model_input[ifm_converter.eye_wink_left_index] += model_input[
ifm_converter.eye_happy_wink_left_index]
model_input[ifm_converter.eye_happy_wink_left_index] = model_input[
ifm_converter.eye_wink_left_index] / 2
model_input[ifm_converter.eye_wink_left_index] = model_input[
ifm_converter.eye_wink_left_index] / 2
model_input[ifm_converter.eye_wink_right_index] += model_input[
ifm_converter.eye_happy_wink_right_index]
model_input[ifm_converter.eye_happy_wink_right_index] = model_input[
ifm_converter.eye_wink_right_index] / 2
model_input[ifm_converter.eye_wink_right_index] = model_input[
ifm_converter.eye_wink_right_index] / 2
uosum = model_input[ifm_converter.mouth_uuu_index - 12] + \
model_input[ifm_converter.mouth_ooo_index - 12]
model_input[ifm_converter.mouth_ooo_index - 12] = uosum
model_input[ifm_converter.mouth_uuu_index - 12] = 0
is_open = (model_input[ifm_converter.mouth_aaa_index - 12] + model_input[
ifm_converter.mouth_iii_index - 12] + uosum) > 0
model_input[ifm_converter.mouth_lowered_corner_left_index - 12] = 0
model_input[ifm_converter.mouth_lowered_corner_right_index - 12] = 0
model_input[ifm_converter.mouth_raised_corner_left_index - 12] = 0.5 if is_open else 0
model_input[ifm_converter.mouth_raised_corner_right_index - 12] = 0.5 if is_open else 0
uosum = model_input[ifm_converter.mouth_uuu_index] + \
model_input[ifm_converter.mouth_ooo_index]
model_input[ifm_converter.mouth_ooo_index] = uosum
model_input[ifm_converter.mouth_uuu_index] = 0
is_open = (model_input[ifm_converter.mouth_aaa_index] + model_input[
ifm_converter.mouth_iii_index] + uosum) > 0
model_input[ifm_converter.mouth_lowered_corner_left_index] = 0
model_input[ifm_converter.mouth_lowered_corner_right_index] = 0
model_input[ifm_converter.mouth_raised_corner_left_index] = 0.5 if is_open else 0
model_input[ifm_converter.mouth_raised_corner_right_index] = 0.5 if is_open else 0
simplify_arr[ifm_converter.mouth_lowered_corner_left_index] = 0
simplify_arr[ifm_converter.mouth_lowered_corner_right_index] = 0
simplify_arr[ifm_converter.mouth_raised_corner_left_index] = 0
@@ -312,8 +314,8 @@ class ModelClientProcess(Process):
simplify_arr[ifm_converter.head_x_index] = 50
simplify_arr[ifm_converter.head_y_index] = 50
simplify_arr[ifm_converter.neck_z_index] = 100
model_input[ifm_converter.eye_raised_lower_eyelid_left_index - 12] = 0
model_input[ifm_converter.eye_raised_lower_eyelid_right_index - 12] = 0
model_input[ifm_converter.eye_raised_lower_eyelid_left_index] = 0
model_input[ifm_converter.eye_raised_lower_eyelid_right_index] = 0
simplify_arr[ifm_converter.iris_rotation_x_index] = 10
simplify_arr[ifm_converter.iris_rotation_y_index] = 10
simplify_arr[ifm_converter.eye_wink_left_index] = 24
@@ -322,43 +324,44 @@ class ModelClientProcess(Process):
simplify_arr[ifm_converter.eye_happy_wink_right_index] = 24
simplify_arr[ifm_converter.eye_surprised_left_index] = 8
simplify_arr[ifm_converter.eye_surprised_right_index] = 8
model_input[ifm_converter.eye_wink_left_index - 12] += model_input[
ifm_converter.eye_wink_right_index - 12]
model_input[ifm_converter.eye_wink_right_index - 12] = model_input[
ifm_converter.eye_wink_left_index - 12] / 2
model_input[ifm_converter.eye_wink_left_index - 12] = model_input[
ifm_converter.eye_wink_left_index - 12] / 2
model_input[ifm_converter.eye_wink_left_index] += model_input[
ifm_converter.eye_wink_right_index]
model_input[ifm_converter.eye_wink_right_index] = model_input[
ifm_converter.eye_wink_left_index] / 2
model_input[ifm_converter.eye_wink_left_index] = model_input[
ifm_converter.eye_wink_left_index] / 2
model_input[ifm_converter.eye_surprised_left_index - 12] += model_input[
ifm_converter.eye_surprised_right_index - 12]
model_input[ifm_converter.eye_surprised_right_index - 12] = model_input[
ifm_converter.eye_surprised_left_index - 12] / 2
model_input[ifm_converter.eye_surprised_left_index - 12] = model_input[
ifm_converter.eye_surprised_left_index - 12] / 2
model_input[ifm_converter.eye_surprised_left_index] += model_input[
ifm_converter.eye_surprised_right_index]
model_input[ifm_converter.eye_surprised_right_index] = model_input[
ifm_converter.eye_surprised_left_index] / 2
model_input[ifm_converter.eye_surprised_left_index] = model_input[
ifm_converter.eye_surprised_left_index] / 2
model_input[ifm_converter.eye_happy_wink_left_index - 12] += model_input[
ifm_converter.eye_happy_wink_right_index - 12]
model_input[ifm_converter.eye_happy_wink_right_index - 12] = model_input[
ifm_converter.eye_happy_wink_left_index - 12] / 2
model_input[ifm_converter.eye_happy_wink_left_index - 12] = model_input[
ifm_converter.eye_happy_wink_left_index - 12] / 2
model_input[ifm_converter.mouth_aaa_index - 12] = min(
model_input[ifm_converter.mouth_aaa_index - 12] +
model_input[ifm_converter.mouth_ooo_index - 12] / 2 +
model_input[ifm_converter.mouth_iii_index - 12] / 2 +
model_input[ifm_converter.mouth_uuu_index - 12] / 2, 1
model_input[ifm_converter.eye_happy_wink_left_index] += model_input[
ifm_converter.eye_happy_wink_right_index]
model_input[ifm_converter.eye_happy_wink_right_index] = model_input[
ifm_converter.eye_happy_wink_left_index] / 2
model_input[ifm_converter.eye_happy_wink_left_index] = model_input[
ifm_converter.eye_happy_wink_left_index] / 2
model_input[ifm_converter.mouth_aaa_index] = min(
model_input[ifm_converter.mouth_aaa_index] +
model_input[ifm_converter.mouth_ooo_index] / 2 +
model_input[ifm_converter.mouth_iii_index] / 2 +
model_input[ifm_converter.mouth_uuu_index] / 2, 1
)
model_input[ifm_converter.mouth_ooo_index - 12] = 0
model_input[ifm_converter.mouth_iii_index - 12] = 0
model_input[ifm_converter.mouth_uuu_index - 12] = 0
model_input[ifm_converter.mouth_ooo_index] = 0
model_input[ifm_converter.mouth_iii_index] = 0
model_input[ifm_converter.mouth_uuu_index] = 0
for i in range(4, args.simplify):
simplify_arr = [max(math.ceil(x * 0.8), 5) for x in simplify_arr]
for i in range(12, len(simplify_arr)):
for i in range(0, len(simplify_arr)):
if simplify_arr[i] > 0:
model_input[i - 12] = round(model_input[i - 12] * simplify_arr[i]) / simplify_arr[i]
model_input[i] = round(model_input[i] * simplify_arr[i]) / simplify_arr[i]
input_hash = hash(tuple(model_input))
cached = model_cache.get(input_hash)
tot += 1
eyebrow_vector_c = [0.0] * 12
mouth_eye_vector_c = [0.0] * 27
if cached is not None and hit_in_a_row < self.model_fps_number.value:
self.output_queue.put_nowait(cached)
@@ -369,15 +372,18 @@ class ModelClientProcess(Process):
hit_in_a_row = 0
if args.perf == 'model':
tic = time.perf_counter()
for i in range(12):
eyebrow_vector[0, i] = model_input[i]
eyebrow_vector_c[i] = model_input[i]
for i in range(27):
mouth_eye_vector[0, i] = model_input[i]
mouth_eye_vector_c[i] = model_input[i]
mouth_eye_vector[0, i] = model_input[i+12]
mouth_eye_vector_c[i] = model_input[i+12]
for i in range(6):
pose_vector[0, i] = model_input[i + 27]
pose_vector[0, i] = model_input[i + 27+12]
if model is None:
output_image = input_image
else:
output_image = model(input_image, mouth_eye_vector, pose_vector, mouth_eye_vector_c,
output_image = model(input_image, mouth_eye_vector, pose_vector, eyebrow_vector, mouth_eye_vector_c, eyebrow_vector_c,
self.gpu_cache_hit_ratio)
if args.perf == 'model':
torch.cuda.synchronize()
@@ -526,6 +532,7 @@ def main():
if args.perf == 'main':
tic = time.perf_counter()
if args.debug_input:
eyebrow_vector_c = [0.0] * 12
mouth_eye_vector_c = [0.0] * 27
pose_vector_c = [0.0] * 6
@@ -574,8 +581,11 @@ def main():
# - ifacialmocap_pose[EYE_LOOK_DOWN_RIGHT]
# + ifacialmocap_pose[EYE_LOOK_DOWN_LEFT]) / 2.0 / 0.75
eyebrow_vector_c = [0.0] * 12
mouth_eye_vector_c = [0.0] * 27
pose_vector_c = [0.0] * 6
for i in range(0, 12):
eyebrow_vector_c[i] = ifacialmocap_pose_converted[i]
for i in range(12, 39):
mouth_eye_vector_c[i - 12] = ifacialmocap_pose_converted[i]
for i in range(39, 42):
@@ -602,6 +612,7 @@ def main():
y_angle = mouse_data['y_angle']
z_angle = mouse_data['z_angle']
eyebrow_vector_c = [0.0] * 12
mouth_eye_vector_c = [0.0] * 27
pose_vector_c = [0.0] * 6
@@ -669,7 +680,8 @@ def main():
pose_vector_c[3] = pose_vector_c[1]
pose_vector_c[4] = pose_vector_c[2]
model_input_arr = mouth_eye_vector_c
model_input_arr = eyebrow_vector_c
model_input_arr.extend(mouth_eye_vector_c)
model_input_arr.extend(pose_vector_c)
model_process.input_queue.put_nowait(model_input_arr)
+88 -45
View File
@@ -13,6 +13,7 @@ from args import args
from collections import OrderedDict
class TalkingAnimeLight(nn.Module):
def __init__(self):
super(TalkingAnimeLight, self).__init__()
@@ -25,54 +26,86 @@ class TalkingAnimeLight(nn.Module):
def forward(self, image, mouth_eye_vector, pose_vector, mouth_eye_vector_c, ratio=None):
x = image.clone()
if args.perf=='model':
tic=time.perf_counter()
if args.perf == 'model':
tic = time.perf_counter()
input_hash = hash(tuple(mouth_eye_vector_c))
cached = self.face_cache.get(input_hash)
self.tot+=1
self.tot += 1
if cached is None:
mouth_eye_morp_image = self.face_morpher(image[:, :, 32:224, 32:224], mouth_eye_vector)
self.face_cache[input_hash]=mouth_eye_morp_image.detach()
self.face_cache[input_hash] = mouth_eye_morp_image.detach()
if len(self.face_cache) > args.max_gpu_cache_len:
self.face_cache.popitem(last=False)
else:
self.hit+=1
mouth_eye_morp_image=cached
self.hit += 1
mouth_eye_morp_image = cached
self.face_cache.move_to_end(input_hash)
if args.debug and ratio is not None:
ratio.value=self.hit / self.tot
if args.perf=='model':
print(" - face_morpher",(time.perf_counter()-tic)*1000)
tic=time.perf_counter()
ratio.value = self.hit / self.tot
if args.perf == 'model':
print(" - face_morpher", (time.perf_counter() - tic) * 1000)
tic = time.perf_counter()
x[:, :, 32:224, 32:224] = mouth_eye_morp_image
rotate_image = self.two_algo_face_rotator(x, pose_vector)[:2]
if args.perf=='model':
print(" - rotator",(time.perf_counter()-tic)*1000)
tic=time.perf_counter()
if args.perf == 'model':
print(" - rotator", (time.perf_counter() - tic) * 1000)
tic = time.perf_counter()
output_image = self.combiner(rotate_image[0], rotate_image[1], pose_vector)
if args.perf=='model':
print(" - combiner",(time.perf_counter()-tic)*1000)
tic=time.perf_counter()
if args.perf == 'model':
print(" - combiner", (time.perf_counter() - tic) * 1000)
tic = time.perf_counter()
return output_image
class TalkingAnime3(nn.Module):
def __init__(self):
super(TalkingAnime3, self).__init__()
if args.model == "standard_float":
self.face_morpher = tha3.poser.modes.standard_float.load_face_morpher('data/models/standard_float/face_morpher.pt')
self.two_algo_face_body_rotator = tha3.poser.modes.standard_float.load_two_algo_generator('data/models/standard_float/two_algo_face_body_rotator.pt')
if args.eyebrow:
self.eyebrow_decomposer = tha3.poser.modes.standard_float.load_eyebrow_decomposer(
'data/models/standard_float/eyebrow_decomposer.pt')
self.eyebrow_morphing_combiner = tha3.poser.modes.standard_float.load_eyebrow_morphing_combiner(
'data/models/standard_float/eyebrow_morphing_combiner.pt')
self.face_morpher = tha3.poser.modes.standard_float.load_face_morpher(
'data/models/standard_float/face_morpher.pt')
self.two_algo_face_body_rotator = tha3.poser.modes.standard_float.load_two_algo_generator(
'data/models/standard_float/two_algo_face_body_rotator.pt')
self.editor = tha3.poser.modes.standard_float.load_editor('data/models/standard_float/editor.pt')
elif args.model == "standard_half":
self.face_morpher = tha3.poser.modes.standard_half.load_face_morpher('data/models/standard_half/face_morpher.pt')
self.two_algo_face_body_rotator = tha3.poser.modes.standard_half.load_two_algo_generator('data/models/standard_half/two_algo_face_body_rotator.pt')
if args.eyebrow:
self.eyebrow_decomposer = tha3.poser.modes.standard_half.load_eyebrow_decomposer(
'data/models/standard_half/eyebrow_decomposer.pt')
self.eyebrow_morphing_combiner = tha3.poser.modes.standard_half.load_eyebrow_morphing_combiner(
'data/models/standard_half/eyebrow_morphing_combiner.pt')
self.face_morpher = tha3.poser.modes.standard_half.load_face_morpher(
'data/models/standard_half/face_morpher.pt')
self.two_algo_face_body_rotator = tha3.poser.modes.standard_half.load_two_algo_generator(
'data/models/standard_half/two_algo_face_body_rotator.pt')
self.editor = tha3.poser.modes.standard_half.load_editor('data/models/standard_half/editor.pt')
elif args.model == "separable_float":
self.face_morpher = tha3.poser.modes.separable_float.load_face_morpher('data/models/separable_float/face_morpher.pt')
self.two_algo_face_body_rotator = tha3.poser.modes.separable_float.load_two_algo_generator('data/models/separable_float/two_algo_face_body_rotator.pt')
if args.eyebrow:
self.eyebrow_decomposer = tha3.poser.modes.separable_float.load_eyebrow_decomposer(
'data/models/separable_float/eyebrow_decomposer.pt')
self.eyebrow_morphing_combiner = tha3.poser.modes.separable_float.load_eyebrow_morphing_combiner(
'data/models/separable_float/eyebrow_morphing_combiner.pt')
self.face_morpher = tha3.poser.modes.separable_float.load_face_morpher(
'data/models/separable_float/face_morpher.pt')
self.two_algo_face_body_rotator = tha3.poser.modes.separable_float.load_two_algo_generator(
'data/models/separable_float/two_algo_face_body_rotator.pt')
self.editor = tha3.poser.modes.separable_float.load_editor('data/models/separable_float/editor.pt')
elif args.model == "separable_half":
self.face_morpher = tha3.poser.modes.separable_half.load_face_morpher('data/models/separable_half/face_morpher.pt')
self.two_algo_face_body_rotator = tha3.poser.modes.separable_half.load_two_algo_generator('data/models/separable_half/two_algo_face_body_rotator.pt')
if args.eyebrow:
self.eyebrow_decomposer = tha3.poser.modes.separable_half.load_eyebrow_decomposer(
'data/models/separable_half/eyebrow_decomposer.pt')
self.eyebrow_morphing_combiner = tha3.poser.modes.separable_half.load_eyebrow_morphing_combiner(
'data/models/separable_half/eyebrow_morphing_combiner.pt')
self.face_morpher = tha3.poser.modes.separable_half.load_face_morpher(
'data/models/separable_half/face_morpher.pt')
self.two_algo_face_body_rotator = tha3.poser.modes.separable_half.load_two_algo_generator(
'data/models/separable_half/two_algo_face_body_rotator.pt')
self.editor = tha3.poser.modes.separable_half.load_editor('data/models/separable_half/editor.pt')
else:
raise RuntimeError("Invalid model: '%s'" % args.model)
@@ -80,40 +113,50 @@ class TalkingAnime3(nn.Module):
self.tot = 0
self.hit = 0
def forward(self, image, mouth_eye_vector, pose_vector, mouth_eye_vector_c, ratio=None):
if args.perf=='model':
tic=time.perf_counter()
def forward(self, image, mouth_eye_vector, pose_vector, eyebrow_vector, mouth_eye_vector_c, eyebrow_vector_c,
ratio=None):
if args.perf == 'model':
tic = time.perf_counter()
x = image.clone()
input_hash = hash(tuple(mouth_eye_vector_c))
if args.eyebrow:
input_hash = hash(tuple(eyebrow_vector_c + mouth_eye_vector_c))
else:
input_hash = hash(tuple(mouth_eye_vector_c))
cached = self.face_cache.get(input_hash)
self.tot+=1
self.tot += 1
if cached is None:
mouth_eye_morp_image = self.face_morpher(image[:, :, 32:32 + 192, (32 + 128):(32 + 192 + 128)], mouth_eye_vector)[0]
self.face_cache[input_hash]=mouth_eye_morp_image.detach()
face_image = x[:, :, 32:32 + 192, (32 + 128):(32 + 192 + 128)].clone()
if args.eyebrow:
eyebrow_morp_image = self.eyebrow_decomposer(x[:, :, 64:192, 64 + 128:192 + 128].clone())
eyebrow_morp_image = \
self.eyebrow_morphing_combiner(eyebrow_morp_image[3], eyebrow_morp_image[0], eyebrow_vector)[2]
face_image[:, :, 32:32 + 128, 32:32 + 128] = eyebrow_morp_image
mouth_eye_morp_image = self.face_morpher(face_image, mouth_eye_vector)[0]
self.face_cache[input_hash] = mouth_eye_morp_image.detach()
if len(self.face_cache) > args.max_gpu_cache_len:
self.face_cache.popitem(last=False)
else:
self.hit+=1
mouth_eye_morp_image=cached
self.hit += 1
mouth_eye_morp_image = cached
self.face_cache.move_to_end(input_hash)
if args.debug and ratio is not None:
ratio.value=self.hit / self.tot
if args.perf=='model':
print(" - face_morpher",(time.perf_counter()-tic)*1000)
tic=time.perf_counter()
ratio.value = self.hit / self.tot
if args.perf == 'model':
print(" - face_morpher", (time.perf_counter() - tic) * 1000)
tic = time.perf_counter()
x[:, :, 32:32 + 192, (32 + 128):(32 + 192 + 128)] = mouth_eye_morp_image
x_half=interpolate(x, size=(256, 256), mode='bilinear', align_corners=False)
x_half = interpolate(x, size=(256, 256), mode='bilinear', align_corners=False)
rotate_image = self.two_algo_face_body_rotator(x_half, pose_vector)
if args.perf=='model':
print(" - rotator",(time.perf_counter()-tic)*1000)
tic=time.perf_counter()
if args.perf == 'model':
print(" - rotator", (time.perf_counter() - tic) * 1000)
tic = time.perf_counter()
output_image = self.editor(x,
interpolate(rotate_image[1], size=(512, 512), mode='bilinear', align_corners=False),
interpolate(rotate_image[2], size=(512, 512), mode='bilinear', align_corners=False),
pose_vector)[0]
if args.perf=='model':
print(" - editor",(time.perf_counter()-tic)*1000)
tic=time.perf_counter()
if args.perf == 'model':
print(" - editor", (time.perf_counter() - tic) * 1000)
tic = time.perf_counter()
return output_image
@@ -127,4 +170,4 @@ class TalkingAnime(nn.Module):
x[:, :, 32:224, 32:224] = mouth_eye_morp_image
rotate_image = self.two_algo_face_rotator(x, pose_vector)[:2]
output_image = self.combiner(rotate_image[0], rotate_image[1], pose_vector)
return output_image
return output_image