diff --git a/.gitignore b/.gitignore index 592d25b..278fbe3 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ __pycache__ -node.zip \ No newline at end of file +node.zip +.DS_Store \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..676e2a4 --- /dev/null +++ b/README.md @@ -0,0 +1,89 @@ +# ComfyUI-Background-Edit + +ComfyUI-Background-Edit is a set of [ComfyUI](https://www.comfy.org/) nodes for editing background of images/videos with CUDA acceleration support. + +Supported use cases: + +- Background blurring +- Background removal +- Background swapping + +The CUDA accelerated nodes can be used in real-time workflows for live video streams using [comfystream](https://github.com/yondonfu/comfystream). + +--- + +- [ComfyUI-Background-Edit](#comfyui-background-edit) +- [Install](#install) + - [Comfy Registry](#comfy-registry) + - [Manual](#manual) +- [Example Real-Time Live Video Workflows](#example-real-time-live-video-workflows) +- [Example Image Workflows](#example-image-workflows) +- [Nodes](#nodes) + +# Install + +The recommended installation method is to use the Comfy Registry. + +## Comfy Registry + +These nodes can be installed via the [Comfy Registry](https://registry.comfy.org/nodes/comfyui-background-edit). + +``` +comfy node registry-install comfyui-background-edit +``` + +## Manual + +These nodes can also be installed manually by copying them into your `custom_nodes` folder and then installing dependencies: + +``` +cd custom_nodes +git clone https://github.com/yondonfu/ComfyUI-Background-Edit +cd ComfyUI-Background-Edit +pip install -r requirements.txt +``` + +# Example Real-Time Live Video Workflows + +**Prerequisites** + +- Install [ComfyUI-Depth-Anything-Tensorrt](https://github.com/yuvraj108c/ComfyUI-Depth-Anything-Tensorrt). + - The example workflow uses TensorRT to accelerate DepthAnything2 to meet real-time requirements. + +The [workflow (API format)](https://github.com/yondonfu/comfystream/blob/main/workflows/depth-bg-blur-gpu-workflow.json) can be used with [comfystream](https://github.com/yondonfu/comfystream) to run real-time background blurring on a live video stream. + +The [workflow](./examples/realtime-depth-bg-blur-workflow.json) can also be saved and dropped into ComfyUI to load the workflow for further modifications. + +# Example Image Workflows + +**Prerequisites**: + +- Install [ComfyUI-DepthAnythingV2](https://github.com/kijai/ComfyUI-DepthAnythingV2). + +The following example workflows are applied to this input image: + +![input](./examples/input.jpg) + +The output images can be saved and dropped into ComfyUI to load the workflows that created them. + +**Background Blurring** + +![depth-bg-blur-output](./examples/depth-bg-blur-output.png) + +**Background Removal** + +![depth-bg-black-output](./examples/depth-bg-black-output.png) + +**Background Swapping** + +![depth-bg-blue-output](./examples/depth-bg-blue-output.png) + +This output just shows the background being swapped to a solid blue color, but in theory the background could be any image of your choice! + +# Nodes + +| Node | Description | +| --------------- | ----------------------------------------------------------------------------------------------------------- | +| BackgroundColor | Creates black/red/green/blue images with same dimensions as input images. | +| Composite | Creates composites of input foreground images, background images and foreground masks (CPU/CUDA supported). | +| GaussianBlur | Applies gaussian blur to input images (CPU/CUDA supported). | \ No newline at end of file diff --git a/examples/depth-bg-black-output.png b/examples/depth-bg-black-output.png new file mode 100644 index 0000000..a8defb6 Binary files /dev/null and b/examples/depth-bg-black-output.png differ diff --git a/examples/depth-bg-blue-output.png b/examples/depth-bg-blue-output.png new file mode 100644 index 0000000..cddb1da Binary files /dev/null and b/examples/depth-bg-blue-output.png differ diff --git a/examples/depth-bg-blur-output.png b/examples/depth-bg-blur-output.png new file mode 100644 index 0000000..071f33c Binary files /dev/null and b/examples/depth-bg-blur-output.png differ diff --git a/examples/input.jpg b/examples/input.jpg new file mode 100644 index 0000000..06d87c3 Binary files /dev/null and b/examples/input.jpg differ diff --git a/examples/realtime-depth-bg-blur-workflow.json b/examples/realtime-depth-bg-blur-workflow.json new file mode 100644 index 0000000..0e83a09 --- /dev/null +++ b/examples/realtime-depth-bg-blur-workflow.json @@ -0,0 +1,352 @@ +{ + "last_node_id": 16, + "last_link_id": 22, + "nodes": [ + { + "id": 8, + "type": "ImageToMask", + "pos": { + "0": 782, + "1": 789 + }, + "size": { + "0": 315, + "1": 58 + }, + "flags": {}, + "order": 3, + "mode": 0, + "inputs": [ + { + "name": "image", + "type": "IMAGE", + "link": 22 + } + ], + "outputs": [ + { + "name": "MASK", + "type": "MASK", + "links": [ + 8 + ], + "slot_index": 0 + } + ], + "properties": { + "Node name for S&R": "ImageToMask" + }, + "widgets_values": [ + "red" + ] + }, + { + "id": 14, + "type": "PreviewImage", + "pos": { + "0": 1574.072998046875, + "1": 487.0025634765625 + }, + "size": [ + 210, + 246 + ], + "flags": {}, + "order": 6, + "mode": 0, + "inputs": [ + { + "name": "images", + "type": "IMAGE", + "link": 17 + } + ], + "outputs": [], + "properties": { + "Node name for S&R": "PreviewImage" + } + }, + { + "id": 10, + "type": "Composite", + "pos": { + "0": 1006, + "1": 527 + }, + "size": { + "0": 315, + "1": 98 + }, + "flags": {}, + "order": 5, + "mode": 0, + "inputs": [ + { + "name": "foregrounds", + "type": "IMAGE", + "link": 11 + }, + { + "name": "backgrounds", + "type": "IMAGE", + "link": 20 + }, + { + "name": "foreground_masks", + "type": "MASK", + "link": 10 + } + ], + "outputs": [ + { + "name": "IMAGE", + "type": "IMAGE", + "links": [ + 17 + ], + "slot_index": 0 + } + ], + "properties": { + "Node name for S&R": "Composite" + }, + "widgets_values": [ + "cuda" + ] + }, + { + "id": 15, + "type": "GaussianBlur", + "pos": { + "0": 595, + "1": 271 + }, + "size": { + "0": 315, + "1": 106 + }, + "flags": {}, + "order": 1, + "mode": 0, + "inputs": [ + { + "name": "images", + "type": "IMAGE", + "link": 19 + } + ], + "outputs": [ + { + "name": "IMAGE", + "type": "IMAGE", + "links": [ + 20 + ], + "slot_index": 0 + } + ], + "properties": { + "Node name for S&R": "GaussianBlur" + }, + "widgets_values": [ + 61, + 7, + "cuda" + ] + }, + { + "id": 1, + "type": "LoadImage", + "pos": { + "0": 85, + "1": 417 + }, + "size": { + "0": 315, + "1": 314 + }, + "flags": {}, + "order": 0, + "mode": 0, + "inputs": [], + "outputs": [ + { + "name": "IMAGE", + "type": "IMAGE", + "links": [ + 11, + 19, + 21 + ], + "slot_index": 0 + }, + { + "name": "MASK", + "type": "MASK", + "links": null + } + ], + "properties": { + "Node name for S&R": "LoadImage" + }, + "widgets_values": [ + "DALLĀ·E 2024-11-15 10.15.49 - An anime-style character standing in a modern office space. The character is a young professional, dressed in a stylish business outfit, with medium-l.jpg", + "image" + ] + }, + { + "id": 9, + "type": "ThresholdMask", + "pos": { + "0": 1160, + "1": 786 + }, + "size": { + "0": 315, + "1": 58 + }, + "flags": {}, + "order": 4, + "mode": 0, + "inputs": [ + { + "name": "mask", + "type": "MASK", + "link": 8 + } + ], + "outputs": [ + { + "name": "MASK", + "type": "MASK", + "links": [ + 10 + ], + "slot_index": 0 + } + ], + "properties": { + "Node name for S&R": "ThresholdMask" + }, + "widgets_values": [ + 0.64 + ] + }, + { + "id": 16, + "type": "DepthAnythingTensorrt", + "pos": { + "0": 463, + "1": 626 + }, + "size": { + "0": 315, + "1": 58 + }, + "flags": {}, + "order": 2, + "mode": 0, + "inputs": [ + { + "name": "images", + "type": "IMAGE", + "link": 21 + } + ], + "outputs": [ + { + "name": "IMAGE", + "type": "IMAGE", + "links": [ + 22 + ], + "slot_index": 0 + } + ], + "properties": { + "Node name for S&R": "DepthAnythingTensorrt" + }, + "widgets_values": [ + "depth_anything_v2_vitb-fp16.engine" + ] + } + ], + "links": [ + [ + 8, + 8, + 0, + 9, + 0, + "MASK" + ], + [ + 10, + 9, + 0, + 10, + 2, + "MASK" + ], + [ + 11, + 1, + 0, + 10, + 0, + "IMAGE" + ], + [ + 17, + 10, + 0, + 14, + 0, + "IMAGE" + ], + [ + 19, + 1, + 0, + 15, + 0, + "IMAGE" + ], + [ + 20, + 15, + 0, + 10, + 1, + "IMAGE" + ], + [ + 21, + 1, + 0, + 16, + 0, + "IMAGE" + ], + [ + 22, + 16, + 0, + 8, + 0, + "IMAGE" + ] + ], + "groups": [], + "config": {}, + "extra": { + "ds": { + "scale": 0.5131581182307067, + "offset": [ + 108.08850273276278, + 324.3584314675088 + ] + } + }, + "version": 0.4 +} \ No newline at end of file