10 Commits
Author SHA1 Message Date
toto fde067c9f5 update node exception 2024-03-07 14:45:08 +08:00
toto f233cae900 Auto update 2024-03-07 14:37:13 +08:00
tototianhao 94dcf5b2d9 Auto update 2024-01-12 01:46:22 +08:00
tototianhao db728d3b70 Auto update 2024-01-12 01:41:04 +08:00
toto 9a7cdbd756 update linux install error 2023-12-29 14:38:03 +08:00
toto 74dce3296d update roop 2023-12-21 12:39:38 +08:00
toto e30f28d20e update ali 2023-12-21 12:35:35 +08:00
TaylorGoulding baa3724ae2 Update README_zh-CN.md 2023-12-18 19:00:42 +08:00
TaylorGoulding 9453492f02 Update README.md 2023-12-18 19:00:24 +08:00
toto b2d44fb139 add mmcv 2023-12-18 16:14:54 +08:00
4 changed files with 32 additions and 28 deletions
-4
View File
@@ -41,10 +41,6 @@ If you have any questions or suggestions, you can reach us through:
## Installation
**Note: When you start the plugin for the first time, it will download all the models required by EasyPhoto. You can see the download progress in the terminal. Please do not interrupt the download (no hash verification for startup speed). If the download is interrupted, you need to manually delete the files downloaded halfway last time and download them again.**
### For Windows users
If you are using a project extracted from a zip package while using ComfyUI, you won't be able to use this plugin. This project relies on ModelScope, but the virtual environment provided in the official ComfyUI zip package cannot install ModelScope. Furthermore, the ComfyUI author has responded, stating that this issue cannot be resolved.[aliyunsdkcor error](https://github.com/ltdrdata/ComfyUI-Impact-Pack/issues/223) If Windows users wish to use this plugin for analyzing and composing ComfyUI workflows, they will need to create their own virtual environment. (I am using Python 3.10.6.).Of course, if you know a solution, feel free to submit a pull request (PR).
### install step
1. First, install ComfyUI.
-4
View File
@@ -44,10 +44,6 @@ English | [简体中文](./README_zh-CN.md)
**注意:初次启动插件的时候会下载EasyPhoto所需要的所有模型,在terminal中可以看到下载进度,请不要中断下载,(为了启动速度,没有做hash校验),如果中断下载,需要手动删除上次下载一半的文件,重新下载。**
### windows用户
如果在使用ComfyUI的时候使用zip包解压后的项目,是无法使用本插件的,本项目依赖modelscope,但是ComfyUI官方zip包中的虚拟环境无法安装modelscope,并且ComfyUI作者已经回复了表示无法解决此问题[aliyunsdkcor error](https://github.com/ltdrdata/ComfyUI-Impact-Pack/issues/223)如果windows用户想使用本插件来分析、组合ComfyUI的流程,请自己创建虚拟环境。(我使用的是python3.10.6),当然如果您知道解决的方法,欢迎提交pr
### 步骤
1. 首先安装ComfyUI
+18 -11
View File
@@ -1,15 +1,18 @@
import os
import sys
import subprocess
import threading
import locale
import traceback
import re
from portrait.config import *
from .config import root_path
plugin_name = os.path.basename(root_path)
windows_not_install = ['mmcv_full\n']
def log(msg, end=None, file=None):
print('Portrait Maker ==============', msg, end=end, file=file)
print(f'{plugin_name} :', msg, end=end, file=file)
def handle_stream(stream, is_stdout):
stream.reconfigure(encoding=locale.getpreferredencoding(), errors='replace')
@@ -21,7 +24,7 @@ def handle_stream(stream, is_stdout):
log(msg, end="", file=sys.stderr)
def process_wrap(cmd_str, cwd=None, handler=None):
log(f"[Portrait Maker] EXECUTE: {cmd_str} in '{cwd}'")
log(f"EXECUTE: {cmd_str} in '{cwd}'")
process = subprocess.Popen(cmd_str, cwd=cwd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True, bufsize=1)
if handler is None:
@@ -48,11 +51,16 @@ def get_installed_packages():
result = subprocess.check_output([sys.executable, '-m', 'pip', 'list'], universal_newlines=True)
pip_list = set([line.split()[0].lower() for line in result.split('\n') if line.strip()])
except subprocess.CalledProcessError as e:
log(f"[ComfyUI-Manager] Failed to retrieve the information of installed pip packages.")
log(f"Failed to retrieve the information of installed pip packages.")
return set()
return pip_list
def mmcv_install():
process_wrap(pip_install + ['-U', 'openmim'], cwd=root_path)
process_wrap(mim_install + ['mmcv-full'], cwd=root_path)
pass
def is_installed(name):
name = name.strip()
pattern = r'([^<>!=]+)([<>!=]=?)'
@@ -87,21 +95,20 @@ def check_and_install_requirements(file_path):
try:
import platform
log("### ComfyUI-Portrait-Maker: Check dependencies")
log("### : Check dependencies")
if "python_embed" in sys.executable or "python_embedded" in sys.executable:
pip_install = [sys.executable, '-s', '-m', 'pip', 'install', '-q']
mim_install = [sys.executable, '-s', '-m', 'mim', 'install']
mim_install = [sys.executable, '-s', '-m', 'mim', 'install', '-q']
else:
pip_install = [sys.executable, '-m', 'pip', 'install', '-q']
mim_install = [sys.executable, '-m', 'mim', 'install']
mim_install = [sys.executable, '-m', 'mim', 'install', '-q']
subpack_req = os.path.join(root_path, "requirements.txt")
# mmcv_install()
check_and_install_requirements(subpack_req)
if platform.system() != "Windows" :
process_wrap(pip_install + ['mmcv_full'], cwd=root_path)
if sys.argv[0] == 'install.py':
sys.path.append('.') # for portable version
sys.path.append('..') # for portable version
except Exception as e:
log("[ERROR] ComfyUI-Impact-Pack: Dependency installation has failed. Please install manually.")
log("Dependency installation has failed. Please install manually.")
traceback.print_exc()
+14 -9
View File
@@ -56,9 +56,9 @@ class FaceFusionPM:
def img_face_fusion(self, source_image, swap_image, mode):
if mode == "ali":
source_image = tensor_to_img(source_image)
swap_image = tensor_to_img(swap_image)
fusion_image = get_image_face_fusion()(dict(template=source_image, user=swap_image))[
source_image_pil = tensor_to_img(source_image)
swap_image_pil = tensor_to_img(swap_image)
fusion_image = get_image_face_fusion()(dict(template=source_image_pil, user=swap_image_pil))[
OutputKeys.OUTPUT_IMG]
result_image = Image.fromarray(cv2.cvtColor(fusion_image, cv2.COLOR_BGR2RGB))
return (img_to_tensor(result_image),)
@@ -75,6 +75,11 @@ class FaceFusionPM:
get_face_analysis().prepare(ctx_id=0, det_size=(640, 640))
faces = get_face_analysis().get(source_np)
swap_faces = get_face_analysis().get(swap_np)
if len(faces) == 0:
raise RuntimeError("No face was recognized in the source image / source image 没有识别到人脸")
if len(swap_faces) == 0:
print("No face was recognized in the swap faces / swap faces没有识别到人脸, 用原脸替换!!!!!!!!!")
return (source_image,)
result_image = get_roop().get(source_np, faces[0], swap_faces[0], paste_back=True)
if need_resize:
image = Image.fromarray(result_image)
@@ -392,9 +397,9 @@ class FaceShapMatchPM:
def faceshap_match(self, source_image, match_image, face_box):
# detect face area
source_image = tensor_to_img(source_image)
match_image = tensor_to_img(match_image)
face_skin_mask = get_face_skin()(source_image, get_retinaface_detection(), needs_index=[[1, 2, 3, 4, 5, 7, 8, 10, 11, 12, 13]])[0]
source_image_copy = tensor_to_img(source_image)
match_image_copy = tensor_to_img(match_image)
face_skin_mask = get_face_skin()(source_image_copy, get_retinaface_detection(), needs_index=[[1, 2, 3, 4, 5, 7, 8, 10, 11, 12, 13]])[0]
face_width = face_box[2] - face_box[0]
kernel_size = np.ones((int(face_width // 10), int(face_width // 10)), np.uint8)
@@ -407,7 +412,7 @@ class FaceShapMatchPM:
# paste back to photo, Using I2I generation controlled solely by OpenPose, even with a very small denoise amplitude,
# still carries the risk of introducing NSFW and global incoherence.!!! important!!!
input_image_uint8 = np.array(source_image) * face_skin_mask + np.array(match_image) * (1 - face_skin_mask)
input_image_uint8 = np.array(source_image_copy) * face_skin_mask + np.array(match_image_copy) * (1 - face_skin_mask)
return (np_to_tensor(input_image_uint8),)
@@ -494,7 +499,7 @@ class SimilarityPM:
"main_image": ("IMAGE",),
"compare_image": ("IMAGE",),
"model": (["sim"],),
"result_prefix": ("STRING",{"default": ""}),
"result_prefix": ("STRING", {"default": ""}),
},
}
@@ -512,7 +517,7 @@ class SimilarityPM:
root_embedding = get_face_recognition()(dict(user=Image.fromarray(np.uint8(main_image_copy))))[OutputKeys.IMG_EMBEDDING]
compare_embedding = get_face_recognition()(dict(user=Image.fromarray(np.uint8(compare_image_copy))))[OutputKeys.IMG_EMBEDDING]
score = float(np.dot(root_embedding, np.transpose(compare_embedding))[0][0])
if result_prefix is "":
if result_prefix == "":
result = str(round(score, 2))
else:
result = f"{result_prefix}_{round(score, 2)}"