update workflow
This commit is contained in:
+146
-98
@@ -1,8 +1,8 @@
|
||||
{
|
||||
"id": "206247b6-9fec-4ed2-8927-e4f388c674d4",
|
||||
"revision": 0,
|
||||
"last_node_id": 142,
|
||||
"last_link_id": 251,
|
||||
"last_node_id": 145,
|
||||
"last_link_id": 254,
|
||||
"nodes": [
|
||||
{
|
||||
"id": 50,
|
||||
@@ -16,7 +16,7 @@
|
||||
200
|
||||
],
|
||||
"flags": {},
|
||||
"order": 17,
|
||||
"order": 18,
|
||||
"mode": 2,
|
||||
"inputs": [
|
||||
{
|
||||
@@ -56,7 +56,7 @@
|
||||
200
|
||||
],
|
||||
"flags": {},
|
||||
"order": 16,
|
||||
"order": 17,
|
||||
"mode": 2,
|
||||
"inputs": [
|
||||
{
|
||||
@@ -202,7 +202,7 @@
|
||||
46
|
||||
],
|
||||
"flags": {},
|
||||
"order": 26,
|
||||
"order": 27,
|
||||
"mode": 0,
|
||||
"inputs": [
|
||||
{
|
||||
@@ -289,7 +289,7 @@
|
||||
198
|
||||
],
|
||||
"flags": {},
|
||||
"order": 32,
|
||||
"order": 33,
|
||||
"mode": 0,
|
||||
"inputs": [
|
||||
{
|
||||
@@ -406,7 +406,7 @@
|
||||
46
|
||||
],
|
||||
"flags": {},
|
||||
"order": 29,
|
||||
"order": 30,
|
||||
"mode": 0,
|
||||
"inputs": [
|
||||
{
|
||||
@@ -502,7 +502,7 @@
|
||||
274
|
||||
],
|
||||
"flags": {},
|
||||
"order": 19,
|
||||
"order": 20,
|
||||
"mode": 0,
|
||||
"inputs": [
|
||||
{
|
||||
@@ -588,7 +588,7 @@
|
||||
"flags": {
|
||||
"collapsed": true
|
||||
},
|
||||
"order": 21,
|
||||
"order": 22,
|
||||
"mode": 2,
|
||||
"inputs": [
|
||||
{
|
||||
@@ -629,7 +629,7 @@
|
||||
246
|
||||
],
|
||||
"flags": {},
|
||||
"order": 22,
|
||||
"order": 23,
|
||||
"mode": 0,
|
||||
"inputs": [
|
||||
{
|
||||
@@ -727,7 +727,7 @@
|
||||
57.857322692871094
|
||||
],
|
||||
"flags": {},
|
||||
"order": 30,
|
||||
"order": 31,
|
||||
"mode": 0,
|
||||
"inputs": [
|
||||
{
|
||||
@@ -769,7 +769,7 @@
|
||||
873.39453125
|
||||
],
|
||||
"flags": {},
|
||||
"order": 31,
|
||||
"order": 32,
|
||||
"mode": 0,
|
||||
"inputs": [
|
||||
{
|
||||
@@ -871,6 +871,15 @@
|
||||
"shape": 7,
|
||||
"type": "FREEINITARGS",
|
||||
"link": null
|
||||
},
|
||||
{
|
||||
"name": "denoise_strength",
|
||||
"shape": 7,
|
||||
"type": "FLOAT",
|
||||
"widget": {
|
||||
"name": "denoise_strength"
|
||||
},
|
||||
"link": 252
|
||||
}
|
||||
],
|
||||
"outputs": [
|
||||
@@ -963,7 +972,7 @@
|
||||
355.67169189453125
|
||||
],
|
||||
"flags": {},
|
||||
"order": 25,
|
||||
"order": 26,
|
||||
"mode": 0,
|
||||
"inputs": [
|
||||
{
|
||||
@@ -1050,7 +1059,7 @@
|
||||
198
|
||||
],
|
||||
"flags": {},
|
||||
"order": 18,
|
||||
"order": 19,
|
||||
"mode": 0,
|
||||
"inputs": [
|
||||
{
|
||||
@@ -1095,58 +1104,6 @@
|
||||
false
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 138,
|
||||
"type": "VideoInputPreprocessor",
|
||||
"pos": [
|
||||
-274.0709533691406,
|
||||
247.68026733398438
|
||||
],
|
||||
"size": [
|
||||
306.6597595214844,
|
||||
194
|
||||
],
|
||||
"flags": {},
|
||||
"order": 24,
|
||||
"mode": 0,
|
||||
"inputs": [
|
||||
{
|
||||
"name": "face_processor",
|
||||
"type": "FACE_PROCESSOR",
|
||||
"link": 242
|
||||
},
|
||||
{
|
||||
"name": "images",
|
||||
"type": "IMAGE",
|
||||
"link": 244
|
||||
},
|
||||
{
|
||||
"name": "face_rgba",
|
||||
"type": "IMAGE",
|
||||
"link": 243
|
||||
}
|
||||
],
|
||||
"outputs": [
|
||||
{
|
||||
"name": "processed_images",
|
||||
"type": "IMAGE",
|
||||
"links": [
|
||||
245
|
||||
]
|
||||
}
|
||||
],
|
||||
"properties": {
|
||||
"aux_id": "WeChatCV/Stand-In_Preprocessor_ComfyUI",
|
||||
"ver": "db0d3d966dada4c5c242f9da5287988b533120e4",
|
||||
"Node name for S&R": "VideoInputPreprocessor"
|
||||
},
|
||||
"widgets_values": [
|
||||
0.5,
|
||||
1.5,
|
||||
10,
|
||||
true
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 134,
|
||||
"type": "WanVideoEncode",
|
||||
@@ -1159,7 +1116,7 @@
|
||||
242
|
||||
],
|
||||
"flags": {},
|
||||
"order": 28,
|
||||
"order": 29,
|
||||
"mode": 0,
|
||||
"inputs": [
|
||||
{
|
||||
@@ -1215,7 +1172,7 @@
|
||||
150
|
||||
],
|
||||
"flags": {},
|
||||
"order": 33,
|
||||
"order": 34,
|
||||
"mode": 0,
|
||||
"inputs": [
|
||||
{
|
||||
@@ -1261,7 +1218,7 @@
|
||||
334
|
||||
],
|
||||
"flags": {},
|
||||
"order": 34,
|
||||
"order": 35,
|
||||
"mode": 0,
|
||||
"inputs": [
|
||||
{
|
||||
@@ -1338,7 +1295,7 @@
|
||||
242
|
||||
],
|
||||
"flags": {},
|
||||
"order": 23,
|
||||
"order": 24,
|
||||
"mode": 0,
|
||||
"inputs": [
|
||||
{
|
||||
@@ -1443,7 +1400,7 @@
|
||||
126
|
||||
],
|
||||
"flags": {},
|
||||
"order": 27,
|
||||
"order": 28,
|
||||
"mode": 0,
|
||||
"inputs": [
|
||||
{
|
||||
@@ -1630,29 +1587,6 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 126,
|
||||
"type": "MarkdownNote",
|
||||
"pos": [
|
||||
-286.70123291015625,
|
||||
-406.58197021484375
|
||||
],
|
||||
"size": [
|
||||
362.6117858886719,
|
||||
143.0945281982422
|
||||
],
|
||||
"flags": {},
|
||||
"order": 15,
|
||||
"mode": 0,
|
||||
"inputs": [],
|
||||
"outputs": [],
|
||||
"properties": {},
|
||||
"widgets_values": [
|
||||
"LoRA link:\n\n[https://huggingface.co/BowenXue/Stand-In](https://huggingface.co/BowenXue/Stand-In)\n\nThis LoRA is not the traditional kind and it HAS TO connect to the model loader directly."
|
||||
],
|
||||
"color": "#432",
|
||||
"bgcolor": "#653"
|
||||
},
|
||||
{
|
||||
"id": 142,
|
||||
"type": "VHS_VideoInfo",
|
||||
@@ -1665,7 +1599,7 @@
|
||||
206
|
||||
],
|
||||
"flags": {},
|
||||
"order": 20,
|
||||
"order": 21,
|
||||
"mode": 0,
|
||||
"inputs": [
|
||||
{
|
||||
@@ -1736,6 +1670,112 @@
|
||||
"Node name for S&R": "VHS_VideoInfo"
|
||||
},
|
||||
"widgets_values": {}
|
||||
},
|
||||
{
|
||||
"id": 126,
|
||||
"type": "MarkdownNote",
|
||||
"pos": [
|
||||
-286.70123291015625,
|
||||
-406.58197021484375
|
||||
],
|
||||
"size": [
|
||||
362.6117858886719,
|
||||
143.0945281982422
|
||||
],
|
||||
"flags": {},
|
||||
"order": 15,
|
||||
"mode": 0,
|
||||
"inputs": [],
|
||||
"outputs": [],
|
||||
"properties": {},
|
||||
"widgets_values": [
|
||||
"LoRA link:\n\n[https://huggingface.co/BowenXue/Stand-In](https://huggingface.co/BowenXue/Stand-In)\n\nThis LoRA is not the traditional kind and it HAS TO connect to the model loader directly."
|
||||
],
|
||||
"color": "#432",
|
||||
"bgcolor": "#653"
|
||||
},
|
||||
{
|
||||
"id": 143,
|
||||
"type": "MarkdownNote",
|
||||
"pos": [
|
||||
-270.9808044433594,
|
||||
479.54229736328125
|
||||
],
|
||||
"size": [
|
||||
300,
|
||||
240
|
||||
],
|
||||
"flags": {},
|
||||
"order": 16,
|
||||
"mode": 0,
|
||||
"inputs": [],
|
||||
"outputs": [],
|
||||
"properties": {},
|
||||
"widgets_values": [
|
||||
"## **With a higher denoise strength, the face blends better with the background, but the background changes slightly more. With a lower denoise strength, the background changes less. You can adjust it according to your needs.**\n"
|
||||
],
|
||||
"color": "#432",
|
||||
"bgcolor": "#653"
|
||||
},
|
||||
{
|
||||
"id": 138,
|
||||
"type": "VideoInputPreprocessor",
|
||||
"pos": [
|
||||
-274.0709533691406,
|
||||
247.68026733398438
|
||||
],
|
||||
"size": [
|
||||
306.6597595214844,
|
||||
194
|
||||
],
|
||||
"flags": {},
|
||||
"order": 25,
|
||||
"mode": 0,
|
||||
"inputs": [
|
||||
{
|
||||
"name": "face_processor",
|
||||
"type": "FACE_PROCESSOR",
|
||||
"link": 242
|
||||
},
|
||||
{
|
||||
"name": "images",
|
||||
"type": "IMAGE",
|
||||
"link": 244
|
||||
},
|
||||
{
|
||||
"name": "face_rgba",
|
||||
"type": "IMAGE",
|
||||
"link": 243
|
||||
}
|
||||
],
|
||||
"outputs": [
|
||||
{
|
||||
"name": "processed_images",
|
||||
"type": "IMAGE",
|
||||
"links": [
|
||||
245
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "denoise_strength",
|
||||
"type": "FLOAT",
|
||||
"links": [
|
||||
252
|
||||
]
|
||||
}
|
||||
],
|
||||
"properties": {
|
||||
"aux_id": "WeChatCV/Stand-In_Preprocessor_ComfyUI",
|
||||
"ver": "db0d3d966dada4c5c242f9da5287988b533120e4",
|
||||
"Node name for S&R": "VideoInputPreprocessor"
|
||||
},
|
||||
"widgets_values": [
|
||||
0.5,
|
||||
0.5,
|
||||
1.5,
|
||||
10,
|
||||
true
|
||||
]
|
||||
}
|
||||
],
|
||||
"links": [
|
||||
@@ -2034,6 +2074,14 @@
|
||||
103,
|
||||
3,
|
||||
"INT"
|
||||
],
|
||||
[
|
||||
252,
|
||||
138,
|
||||
1,
|
||||
27,
|
||||
17,
|
||||
"FLOAT"
|
||||
]
|
||||
],
|
||||
"groups": [
|
||||
@@ -2054,10 +2102,10 @@
|
||||
"config": {},
|
||||
"extra": {
|
||||
"ds": {
|
||||
"scale": 0.6115909044841601,
|
||||
"scale": 0.8140274938684186,
|
||||
"offset": [
|
||||
1552.3325791014386,
|
||||
871.5007309079728
|
||||
1354.2272102810791,
|
||||
250.24273344699088
|
||||
]
|
||||
},
|
||||
"frontendVersion": "1.24.4",
|
||||
|
||||
+5
-8
@@ -28,6 +28,7 @@ class VideoInputPreprocessor:
|
||||
"face_processor": ("FACE_PROCESSOR",),
|
||||
"images": ("IMAGE",),
|
||||
"face_rgba": ("IMAGE",),
|
||||
"denoise_strength": ("FLOAT", {"default": 0.5, "min": 0.1, "max": 1.0, "step": 0.01}),
|
||||
"confidence_threshold": ("FLOAT", {"default": 0.5, "min": 0.1, "max": 1.0, "step": 0.05}),
|
||||
"face_crop_scale": ("FLOAT", {"default": 1.5, "min": 1.0, "max": 3.0, "step": 0.1}),
|
||||
"dilation_kernel_size": ("INT", {"default": 10, "min": 0, "max": 50, "step": 1}),
|
||||
@@ -35,12 +36,12 @@ class VideoInputPreprocessor:
|
||||
}
|
||||
}
|
||||
|
||||
RETURN_TYPES = ("IMAGE",)
|
||||
RETURN_NAMES = ("processed_images",)
|
||||
RETURN_TYPES = ("IMAGE", "FLOAT")
|
||||
RETURN_NAMES = ("processed_images", "denoise_strength")
|
||||
FUNCTION = "generate_mask_and_paste"
|
||||
CATEGORY = "Stand-In"
|
||||
|
||||
def generate_mask_and_paste(self, face_processor, images: torch.Tensor, face_rgba: torch.Tensor, confidence_threshold: float, face_crop_scale: float, dilation_kernel_size: int, with_neck: bool):
|
||||
def generate_mask_and_paste(self, face_processor, images: torch.Tensor, face_rgba: torch.Tensor, denoise_strength: float, confidence_threshold: float, face_crop_scale: float, dilation_kernel_size: int, with_neck: bool):
|
||||
detection_model, parsing_model, device = face_processor
|
||||
total_frames, h, w = images.shape[0], images.shape[1], images.shape[2]
|
||||
|
||||
@@ -59,7 +60,6 @@ class VideoInputPreprocessor:
|
||||
frame_tensor = images[i]
|
||||
frame_bgr = tensor_to_cv2_img(frame_tensor)
|
||||
|
||||
# --- 1. Generate Face Mask (same logic as before) ---
|
||||
results = detection_model(frame_bgr, verbose=False)
|
||||
confident_boxes = results[0].boxes.xyxy[results[0].boxes.conf > confidence_threshold]
|
||||
|
||||
@@ -101,11 +101,8 @@ class VideoInputPreprocessor:
|
||||
mask_resized_to_crop = cv2.resize(final_mask_512, (face_crop_bgr.shape[1], face_crop_bgr.shape[0]), interpolation=cv2.INTER_NEAREST)
|
||||
full_mask_np[crop_y1:crop_y2, crop_x1:crop_x2] = mask_resized_to_crop
|
||||
|
||||
# --- 2. Paste Image onto Frame ---
|
||||
# Use a copy to avoid modifying the original data
|
||||
target_frame_pil = tensor_to_pil(frame_tensor).copy()
|
||||
|
||||
# Find the bounding box of the largest contour in the mask
|
||||
if confident_boxes.shape[0] > 0 and 'face_crop_bgr' in locals() and face_crop_bgr.size > 0:
|
||||
|
||||
x = crop_x1
|
||||
@@ -125,7 +122,7 @@ class VideoInputPreprocessor:
|
||||
output_image_batch = torch.stack(processed_frames_tensors)
|
||||
|
||||
|
||||
return (output_image_batch,)
|
||||
return (output_image_batch,denoise_strength)
|
||||
|
||||
NODE_CLASS_MAPPINGS = {
|
||||
"VideoInputPreprocessor": VideoInputPreprocessor,
|
||||
|
||||
Reference in New Issue
Block a user