add two super node, simplify progress

This commit is contained in:
toto
2023-10-25 21:15:49 +08:00
parent 4abaf4cd92
commit d9ade2e531
5 changed files with 87 additions and 5 deletions
+5
View File
@@ -13,6 +13,11 @@ If you have any questions or suggestions, you can reach us through:
- QQ Group: 10419777
- WeChat Group: <img src="./images/wechat.jpg" width="200">
## V1.2.0 Update
1. Add PM_SuperColorTransfer node to simplify the color transfer process
2. Add PM_SuperMakeUpTransfer node to simplify the process of makeup transfer
## V1.1.0 Update
1. faceskin adds blur option
2. Add PM_FaceShapMatch node. same as easyphot faceshap match
+4
View File
@@ -15,6 +15,10 @@ English | [简体中文](./README_zh-CN.md)
- QQ 群:10419777
- 微信群: <img src="./images/wechat.jpg" width="200">
## V1.2.0 Update
1. 增加PM_SuperColorTransfer 节点,简化了颜色迁移的流程
2. 增加PM_SuperMakeUpTransfer 节点,简化了进行装扮迁移的流程
## v1.1.0 更新
1. faceskin 增加模糊选项
2. 增加 PM_FaceShapMatch节点 与easyphoto的FaceshapMatch一致
+5 -1
View File
@@ -77,6 +77,8 @@ NODE_CLASS_MAPPINGS = {
"PM_GetImageInfo": GetImageInfoPM,
"PM_MakeUpTransfer": MakeUpTransferPM,
"PM_FaceShapMatch": FaceShapMatchPM,
"PM_SuperColorTransfer": SuperColorTransferPM,
"PM_SuperMakeUpTransfer": SuperMakeUpTransferPM,
}
NODE_DISPLAY_NAME_MAPPINGS = {
"PM_RetinaFace": "RetinaFace PM",
@@ -95,7 +97,9 @@ NODE_DISPLAY_NAME_MAPPINGS = {
"PM_ImageResizeTarget": "ImageResizeTarget PM",
"PM_GetImageInfo": "GetImageInfo PM",
"PM_MakeUpTransfer": "MakeUpTransfer PM",
"PM_FaceShapMatch":"FaceShapMatch PM"
"PM_FaceShapMatch": "FaceShapMatch PM",
"PM_SuperColorTransfer": "SuperColorTransfer PM",
"PM_SuperMakeUpTransfer": "SuperMakeUpTransfer PM",
}
__all__ = ['NODE_CLASS_MAPPINGS', 'NODE_DISPLAY_NAME_MAPPINGS']
BIN
View File
Binary file not shown.

Before

Width:  |  Height:  |  Size: 105 KiB

After

Width:  |  Height:  |  Size: 280 KiB

+73 -4
View File
@@ -6,8 +6,9 @@ from .utils.face_process_utils import call_face_crop, color_transfer, Face_Skin
from .utils.img_utils import img_to_tensor, tensor_to_img, tensor_to_np, np_to_tensor, np_to_mask, img_to_mask, img_to_np
from .model_holder import *
# import pydevd_pycharm
# pydevd_pycharm.settrace('49.7.62.197', port=10090, stdoutToServer=True, stderrToServer=True)
import pydevd_pycharm
pydevd_pycharm.settrace('49.7.62.197', port=10090, stdoutToServer=True, stderrToServer=True)
class RetinaFacePM:
@classmethod
@@ -348,8 +349,6 @@ class MakeUpTransferPM:
CATEGORY = "protrait/model"
def makeup_transfer(self, source_image, makeup_image):
source_image = tensor_to_img(source_image).resize([256, 256])
makeup_image = tensor_to_img(makeup_image).resize([256, 256])
result = get_pagan_interface().transfer(source_image, makeup_image)
return (img_to_tensor(result),)
@@ -389,3 +388,73 @@ class FaceShapMatchPM:
input_image_uint8 = np.array(source_image) * face_skin_mask + np.array(match_image) * (1 - face_skin_mask)
return (np_to_tensor(input_image_uint8),)
class SuperColorTransferPM:
@classmethod
def INPUT_TYPES(s):
return \
{
"required": {
"main_image": ("IMAGE",),
"transfer_image": ("IMAGE",),
},
"optional": {
"avatar_box": ("BOX",),
},
}
RETURN_TYPES = ("IMAGE",)
FUNCTION = "super_color_transfer"
CATEGORY = "protrait/model"
def super_color_transfer(self, main_image, transfer_image, avatar_box=None):
origin_np = tensor_to_np(main_image)
if avatar_box is not None:
main_image = main_image[:, avatar_box[1]:avatar_box[3], avatar_box[0]:avatar_box[2], :]
transfer_image = transfer_image[:, avatar_box[1]:avatar_box[3], avatar_box[0]:avatar_box[2], :]
transfer_result = color_transfer(tensor_to_np(main_image), tensor_to_np(transfer_image)) # 进行颜色迁移
face_skin_img = get_face_skin()(Image.fromarray(transfer_result), get_retinaface_detection(), [[1, 2, 3, 4, 5, 10, 12, 13]])[0]
face_skin_np = img_to_np(face_skin_img)
face_skin_np = cv2.blur(face_skin_np, (32, 32)) / 255
masked_img_np = tensor_to_np(main_image) * (1 - face_skin_np) + transfer_result * face_skin_np
origin_np[avatar_box[1]:avatar_box[3], avatar_box[0]:avatar_box[2], :] = masked_img_np
return (np_to_tensor(origin_np),)
class SuperMakeUpTransferPM:
@classmethod
def INPUT_TYPES(s):
return \
{
"required": {
"main_image": ("IMAGE",),
"makeup_image": ("IMAGE",),
},
"optional": {
"avatar_box": ("BOX",),
},
}
RETURN_TYPES = ("IMAGE",)
FUNCTION = "super_makeup_transfer"
CATEGORY = "protrait/model"
def super_makeup_transfer(self, main_image, makeup_image, avatar_box=None):
box_width, box_height = avatar_box[2] - avatar_box[0], avatar_box[3] - avatar_box[1]
origin_np = tensor_to_np(main_image)
if avatar_box is not None:
main_image = main_image[:, avatar_box[1]:avatar_box[3], avatar_box[0]:avatar_box[2], :]
makeup_image = makeup_image[:, avatar_box[1]:avatar_box[3], avatar_box[0]:avatar_box[2], :]
resize_source_box_image = tensor_to_img(main_image).resize([256, 256])
resize_makeup_box_image = tensor_to_img(makeup_image).resize([256, 256])
transfer_image = get_pagan_interface().transfer(resize_source_box_image, resize_makeup_box_image)
box_size_transfer = transfer_image.resize([box_width, box_height], Image.Resampling.LANCZOS)
origin_np[avatar_box[1]:avatar_box[3], avatar_box[0]:avatar_box[2], :] = img_to_np(box_size_transfer)
return (np_to_tensor(origin_np),)