什么是 ReActor?
face swap 作为 deepfake 几年前已存在,但当时有必要集齐几百张同一人物的脸部图像进行学习。
ReActor(正确地说是那个核心 InsightFace ),可以只以 1 张脸部照片为参照,替换映在别的图像或视频的脸。
现在虽然以扩散模型为基础的更柔软的 ID 传送手段也登场了,但 ReActor 凭借“比较轻”“好意义上的没有柔软性(严密)并安定”等理由,现在也是被经常使用的方法。
自定义节点和安装
安装方法
这个节点导入稍微有点难,只从 ComfyUI Manager 安装是不会动的。
-
- 从 ComfyUI Manager 安装 ReActor 节点。
-
- 执行在
ComfyUI/custom_nodes/ComfyUI-ReActor 的 install.bat。
-
- Windows 用户只做这些动不了,必须另外安装 InsightFace。
-
- 重启 ComfyUI。
FaceSwap(inswapper)
基本的 FaceSwap,只是向 ReActor 节点输入“元图像”和“参照脸图像”。
ReActor_Fast_Face_Swap.json
{
"id": "1b2ef2ef-9149-46e0-a6c1-7beda89a1fe6",
"revision": 0,
"last_node_id": 14,
"last_link_id": 23,
"nodes": [
{
"id": 12,
"type": "LoadImage",
"pos": [
160.4533870022538,
834.9161229359444
],
"size": [
496.38248812500007,
534.2926
],
"flags": {},
"order": 0,
"mode": 0,
"inputs": [],
"outputs": [
{
"name": "IMAGE",
"type": "IMAGE",
"links": [
21
]
},
{
"name": "MASK",
"type": "MASK",
"links": null
}
],
"properties": {
"cnr_id": "comfy-core",
"ver": "0.3.76",
"Node name for S&R": "LoadImage"
},
"widgets_values": [
"pasted/image (6).png",
"image"
]
},
{
"id": 2,
"type": "LoadImage",
"pos": [
160.4533870022538,
311.54146328666025
],
"size": [
497.8093985382229,
461.5989689256197
],
"flags": {},
"order": 1,
"mode": 0,
"inputs": [],
"outputs": [
{
"name": "IMAGE",
"type": "IMAGE",
"links": [
20
]
},
{
"name": "MASK",
"type": "MASK",
"links": null
}
],
"properties": {
"cnr_id": "comfy-core",
"ver": "0.3.76",
"Node name for S&R": "LoadImage"
},
"widgets_values": [
"pasted/image (8).png",
"image"
]
},
{
"id": 1,
"type": "ReActorFaceSwap",
"pos": [
697.0210160550583,
311.54146328666025
],
"size": [
302.6424812758264,
358
],
"flags": {},
"order": 2,
"mode": 0,
"inputs": [
{
"name": "input_image",
"type": "IMAGE",
"link": 20
},
{
"name": "source_image",
"shape": 7,
"type": "IMAGE",
"link": 21
},
{
"name": "face_model",
"shape": 7,
"type": "FACE_MODEL",
"link": null
},
{
"name": "face_boost",
"shape": 7,
"type": "FACE_BOOST",
"link": null
}
],
"outputs": [
{
"name": "SWAPPED_IMAGE",
"type": "IMAGE",
"links": [
23
]
},
{
"name": "FACE_MODEL",
"type": "FACE_MODEL",
"links": null
},
{
"name": "ORIGINAL_IMAGE",
"type": "IMAGE",
"links": null
}
],
"properties": {
"Node name for S&R": "ReActorFaceSwap"
},
"widgets_values": [
true,
"inswapper_128.onnx",
"retinaface_resnet50",
"GFPGANv1.3.pth",
0.5,
0.5,
"no",
"no",
"0,2",
"0,1",
1
],
"color": "#232",
"bgcolor": "#353"
},
{
"id": 14,
"type": "SaveImage",
"pos": [
1038.4217278454664,
311.54146328666025
],
"size": [
701.97,
560.1500000000001
],
"flags": {},
"order": 3,
"mode": 0,
"inputs": [
{
"name": "images",
"type": "IMAGE",
"link": 23
}
],
"outputs": [],
"properties": {
"cnr_id": "comfy-core",
"ver": "0.3.76"
},
"widgets_values": [
"ComfyUI"
]
}
],
"links": [
[
20,
2,
0,
1,
0,
"IMAGE"
],
[
21,
12,
0,
1,
1,
"IMAGE"
],
[
23,
1,
0,
14,
0,
"IMAGE"
]
],
"groups": [],
"config": {},
"extra": {
"ds": {
"scale": 0.8264462809917354,
"offset": [
-60.453387002253805,
-211.54146328666025
]
},
"workflowRendererVersion": "LG",
"frontendVersion": "1.33.10",
"VHS_latentpreview": false,
"VHS_latentpreviewrate": 0,
"VHS_MetadataImage": true,
"VHS_KeepIntermediate": true
},
"version": 0.4
}
此外,简单总结经常使用的参数。
face_restore_model
- 如果选择
GFPGANv1.3,FaceSwap 后会进行由 GFPGAN 带来的脸部修补。
inswapper 因为将脸的部分调整为 128px 四方进行处理,那样的话容易丢失细节,所以这样的后处理变得重要。
- 只是,需要注意这点:无论如何都容易变成平板(不立体)的印象。
detect_gender_input / detect_gender_source
- 是否自动判定输入图像・参照图像的性别的设定。
- 因性别的差异导致结果变得不自然的情况,试着切换 ON/OFF 也许好。
input_faces_index
- 元图像中有复数人的脸的情况,指定以哪张脸为对象。
- 是
0 为最初找到的脸,1 为第 2 人……这样的印象。
- 像
0,1 这样以逗号分隔指定复数的话,也可以同时置换复数人。
source_faces_index
- 参照侧的
source_image 也有复数人的脸的情况,与 input_faces_index 同样指定使用哪张脸。
使用别的 FaceSwap 模型(HyperSwap)
虽然刚才使用的 inswapper 是旧模型,但考虑社会影响,被开发者封印了高分辨率版。
虽然有几个代替模型,试着使用 FaceFusion Labs 开发的 HyperSwap 吧。
模型的下载
📂ComfyUI/
└── 📂models/
└── 📂hyperswap/
└── hyperswap_1a_256.onnx
工作流的设定
{
"id": "1b2ef2ef-9149-46e0-a6c1-7beda89a1fe6",
"revision": 0,
"last_node_id": 15,
"last_link_id": 23,
"nodes": [
{
"id": 12,
"type": "LoadImage",
"pos": [
160.4533870022538,
834.9161229359444
],
"size": [
496.38248812500007,
534.2926
],
"flags": {},
"order": 0,
"mode": 0,
"inputs": [],
"outputs": [
{
"name": "IMAGE",
"type": "IMAGE",
"links": [
21
]
},
{
"name": "MASK",
"type": "MASK",
"links": null
}
],
"properties": {
"cnr_id": "comfy-core",
"ver": "0.3.76",
"Node name for S&R": "LoadImage"
},
"widgets_values": [
"pasted/image (10).png",
"image"
]
},
{
"id": 2,
"type": "LoadImage",
"pos": [
160.4533870022538,
311.54146328666025
],
"size": [
497.8093985382229,
461.5989689256197
],
"flags": {},
"order": 1,
"mode": 0,
"inputs": [],
"outputs": [
{
"name": "IMAGE",
"type": "IMAGE",
"links": [
20
]
},
{
"name": "MASK",
"type": "MASK",
"links": null
}
],
"properties": {
"cnr_id": "comfy-core",
"ver": "0.3.76",
"Node name for S&R": "LoadImage"
},
"widgets_values": [
"pasted/image (11).png",
"image"
]
},
{
"id": 1,
"type": "ReActorFaceSwap",
"pos": [
697.7024819970889,
311.54146328666025
],
"size": [
302.6424812758264,
358
],
"flags": {},
"order": 2,
"mode": 0,
"inputs": [
{
"name": "input_image",
"type": "IMAGE",
"link": 20
},
{
"name": "source_image",
"shape": 7,
"type": "IMAGE",
"link": 21
},
{
"name": "face_model",
"shape": 7,
"type": "FACE_MODEL",
"link": null
},
{
"name": "face_boost",
"shape": 7,
"type": "FACE_BOOST",
"link": null
}
],
"outputs": [
{
"name": "SWAPPED_IMAGE",
"type": "IMAGE",
"links": [
23
]
},
{
"name": "FACE_MODEL",
"type": "FACE_MODEL",
"links": null
},
{
"name": "ORIGINAL_IMAGE",
"type": "IMAGE",
"links": null
}
],
"properties": {
"Node name for S&R": "ReActorFaceSwap"
},
"widgets_values": [
true,
"hyperswap_1a_256.onnx",
"retinaface_resnet50",
"GFPGANv1.3.pth",
0.5,
0.5,
"no",
"no",
"0",
"0",
1
],
"color": "#232",
"bgcolor": "#353"
},
{
"id": 15,
"type": "SaveImage",
"pos": [
1039.7846597295274,
311.54146328666025
],
"size": [
701.97,
560.1500000000001
],
"flags": {},
"order": 3,
"mode": 0,
"inputs": [
{
"name": "images",
"type": "IMAGE",
"link": 23
}
],
"outputs": [],
"properties": {
"cnr_id": "comfy-core",
"ver": "0.3.76"
},
"widgets_values": [
"ComfyUI"
]
}
],
"links": [
[
20,
2,
0,
1,
0,
"IMAGE"
],
[
21,
12,
0,
1,
1,
"IMAGE"
],
[
23,
1,
0,
15,
0,
"IMAGE"
]
],
"groups": [],
"config": {},
"extra": {
"ds": {
"scale": 0.7513148009015777,
"offset": [
-60.453387002253805,
-211.54146328666025
]
},
"workflowRendererVersion": "LG",
"frontendVersion": "1.33.10",
"VHS_latentpreview": false,
"VHS_latentpreviewrate": 0,
"VHS_MetadataImage": true,
"VHS_KeepIntermediate": true
},
"version": 0.4
}
- 将 ReActor 节点的
swap_model,变更为 hyperswap_1a_256。
关于 NSFW 过滤器
为了不让存储库被删除,ReActor 加入了针对 NSFW 图像的过滤器。
因此,使用包含 NSFW 的图像的情况会被拒绝。
虽然不会说得太详细,但可以用简单的手段回避。
( Detailer 也许……会有用 )