From 8ec5337668eae23f21d66df7d320bab0477cd23a Mon Sep 17 00:00:00 2001 From: shadowcz007 Date: Thu, 8 Aug 2024 22:58:23 +0800 Subject: [PATCH] ExpressionVideo2VideoNode --- __init__.py | 8 ++++-- nodes/expression_editor.py | 58 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 63 insertions(+), 3 deletions(-) diff --git a/__init__.py b/__init__.py index ffe28fd..2404ae8 100644 --- a/__init__.py +++ b/__init__.py @@ -1,5 +1,5 @@ from .nodes.live_portrait import LivePortraitNode,FaceCropInfo,Retargeting,LivePortraitVideoNode -from .nodes.expression_editor import ExpressionEditor,ExpressionVideoNode +from .nodes.expression_editor import ExpressionEditor,ExpressionVideoNode,ExpressionVideo2VideoNode NODE_CLASS_MAPPINGS = { "LivePortraitNode": LivePortraitNode, @@ -7,7 +7,8 @@ NODE_CLASS_MAPPINGS = { "FaceCropInfo":FaceCropInfo, "Retargeting":Retargeting, "ExpressionEditor_":ExpressionEditor, - "ExpressionVideoNode":ExpressionVideoNode + "ExpressionVideoNode":ExpressionVideoNode, + "ExpressionVideo2VideoNode":ExpressionVideo2VideoNode } # dict = { "key":value } @@ -18,7 +19,8 @@ NODE_DISPLAY_NAME_MAPPINGS = { "FaceCropInfo":"Face Crop Info", "Retargeting":"Retargeting", "ExpressionEditor_":"Expression Editor", - "ExpressionVideoNode":"Expression Video" + "ExpressionVideoNode":"Expression Video", + "ExpressionVideo2VideoNode":"Expression Video 2 Video" } # web ui的节点功能 diff --git a/nodes/expression_editor.py b/nodes/expression_editor.py index 0af2bcc..2cac720 100644 --- a/nodes/expression_editor.py +++ b/nodes/expression_editor.py @@ -540,7 +540,65 @@ class ExpressionVideoNode: result=torch.cat(result, dim=0) return (result,) + + +# +class ExpressionVideo2VideoNode: + def __init__(self): + self.src_image = None + @classmethod + def INPUT_TYPES(s): + + return {"required": { + "src_frames": ("IMAGE",), #batch + "from_expression":("STRING", {"forceInput": True,"dynamicPrompts": False}), + "to_expression":("STRING", {"forceInput": True,"dynamicPrompts": False}), + "interpolation_type":( ['linear', 'nearest', 'cubic'], + {"default": "cubic"}), + }, + } + RETURN_TYPES = ("IMAGE",) + RETURN_NAMES = ("frames",) + + FUNCTION = "run" + + # OUTPUT_NODE = True + + CATEGORY = "♾️Mixlab/Video/LivePortrait" + + INPUT_IS_LIST = False + OUTPUT_IS_LIST = (False,) #x list + + def run(self,src_frames,from_expression, to_expression,interpolation_type ): + + images = [src_frames[i:i + 1, ...] for i in range(src_frames.shape[0])] + interpolations_num=len(images) + + from_expression = json.loads(from_expression) + to_expression = json.loads(to_expression) + + from_expression=update_expression_json(from_expression) + to_expression=update_expression_json(to_expression) + + exps=interpolate_dicts(from_expression,to_expression,interpolations_num,interpolation_type) + + result=[] + + for i in range(interpolations_num): + + src_image = images[i] + exp=exps[i] + + self.psi = g_engine.prepare_source(src_image) + self.src_image = src_image + + out_img = expression_run(self.psi,exp) + result.append(out_img) + + result=torch.cat(result, dim=0) + + return (result,) class ExpressionEditor: def __init__(self):