[Added] Nodes for normalization
Useful for testing models or using low level models
This commit is contained in:
@@ -20,6 +20,9 @@ Currently we just have a few nodes used by other nodes I maintain.
|
||||
- [Image Download and Load](#1-image-download-and-load)
|
||||
- [Face Composite](#2-face-composite)
|
||||
- [Face Composite (frame by frame)](#3-face-composite-frame-by-frame)
|
||||
- [Normalize Image to ImageNet](#4-normalize-image-to-imagenet)
|
||||
- [Normalize Image to [-0.5, 0.5]](#5-normalize-image-to-05-05)
|
||||
- [Normalize Image to [-1, 1]](#6-normalize-image-to-1-1)
|
||||
- 📝 [Usage Notes](#-usage-notes)
|
||||
- 📜 [Project History](#-project-history)
|
||||
- ⚖️ [License](#️-license)
|
||||
@@ -81,6 +84,50 @@ Currently we just have a few nodes used by other nodes I maintain.
|
||||
- **How it Works:** The node iterates from frame 0 to N-1. In each step, it takes the i-th `animated` frame and the i-th `reference` frame. It then pastes the animated frame onto the reference frame using the coordinates from the single, static bounding box.
|
||||
|
||||
|
||||
### 4. Normalize Image to ImageNet
|
||||
- **Display Name:** `"Normalize Image to ImageNet`
|
||||
- **Internal Name:** `SET_NormalizeToImageNetDataset`
|
||||
- **Category:** `image/normalization`
|
||||
- **Description:** Normalizes an image tensor using the mean and standard deviation of the ImageNet dataset.
|
||||
- **Purpose:** Essential for pre-processing images before feeding them into models that were pre-trained on ImageNet (e.g., most ResNet, VGG, EfficientNet models).
|
||||
- **Inputs:**
|
||||
- `image` (`IMAGE`): A standard ComfyUI image tensor in the `[0, 1]` range.
|
||||
- **Output:**
|
||||
- `image` (`IMAGE`): The normalized image tensor. The value range will be altered significantly.
|
||||
- **How it Works:** For each channel, it performs the operation `output = (input - mean) / std`, using the standard ImageNet values:
|
||||
- **Mean:** `[0.485, 0.456, 0.406]`
|
||||
- **Std Dev:** `[0.229, 0.224, 0.225]`
|
||||
|
||||
### 5. Normalize Image to [-0.5, 0.5]
|
||||
|
||||
- **Display Name:** `Normalize Image to [-0.5, 0.5]`
|
||||
- **Internal Name:** `SET_NormalizeToMinus05_05`
|
||||
- **Category:** `image/normalization`
|
||||
- **Description:** Normalizes an image tensor by centering its values around zero.
|
||||
- **Purpose:** Useful for models trained from scratch or those that expect input data in the `[-0.5, 0.5]` range. This can help stabilize training.
|
||||
- **Inputs:**
|
||||
- `image` (`IMAGE`): A standard ComfyUI image tensor in the `[0, 1]` range.
|
||||
- **Output:**
|
||||
- `image` (`IMAGE`): The normalized image tensor, with values in the `[-0.5, 0.5]` range.
|
||||
- **How it Works:** For each channel, it performs the operation `output = (input - mean) / std`, using:
|
||||
- **Mean:** `[0.5, 0.5, 0.5]`
|
||||
- **Std Dev:** `[1.0, 1.0, 1.0]`
|
||||
|
||||
### 6. Normalize Image to [-1, 1]
|
||||
|
||||
- **Display Name:** `Normalize Image to [-1, 1]`
|
||||
- **Internal Name:** `SET_NormalizeToMinus1_1`
|
||||
- **Category:** `image/normalization`
|
||||
- **Description:** Normalizes an image tensor to the `[-1, 1]` range.
|
||||
- **Purpose:** A common requirement for certain model architectures, particularly Generative Adversarial Networks (GANs) and models using the `tanh` activation function in their output layer.
|
||||
- **Inputs:**
|
||||
- `image` (`IMAGE`): A standard ComfyUI image tensor in the `[0, 1]` range.
|
||||
- **Output:**
|
||||
- `image` (`IMAGE`): The normalized image tensor, with values in the `[-1, 1]` range.
|
||||
- **How it Works:** For each channel, it performs the operation `output = (input - mean) / std`, using:
|
||||
- **Mean:** `[0.5, 0.5, 0.5]`
|
||||
- **Std Dev:** `[0.5, 0.5, 0.5]`
|
||||
|
||||
## 🚀 Installation
|
||||
|
||||
You can install the nodes from the ComfyUI nodes manager, the name is *Image Misc*, or just do it manually:
|
||||
|
||||
@@ -11,6 +11,7 @@ from seconohe.downloader import download_file
|
||||
# We are the main source, so we use the main_logger
|
||||
from . import main_logger
|
||||
import torch
|
||||
import torchvision.transforms.functional as TF
|
||||
from typing import Optional
|
||||
try:
|
||||
from folder_paths import get_input_directory # To get the ComfyUI input directory
|
||||
@@ -29,6 +30,7 @@ logger = main_logger
|
||||
BASE_CATEGORY = "image"
|
||||
IO_CATEGORY = "io"
|
||||
MANIPULATION_CATEGORY = "manipulation"
|
||||
NORMALIZATION = "normalization"
|
||||
|
||||
|
||||
def tensor_to_pil(tensor: torch.Tensor) -> Image.Image:
|
||||
@@ -315,3 +317,73 @@ class CompositeFaceFrameByFrame(CompositeFace):
|
||||
final_batch = torch.stack(output_images)
|
||||
|
||||
return (final_batch,)
|
||||
|
||||
|
||||
class NormalizeToImageNetDataset():
|
||||
"""
|
||||
A ComfyUI node to normalize the values to the mean/std of the ImageNet dataset
|
||||
"""
|
||||
@classmethod
|
||||
def INPUT_TYPES(cls):
|
||||
return {
|
||||
"required": {
|
||||
"image": ("IMAGE",),
|
||||
},
|
||||
}
|
||||
RETURN_TYPES = ("IMAGE",)
|
||||
RETURN_NAMES = ("image",)
|
||||
FUNCTION = "normalize"
|
||||
CATEGORY = BASE_CATEGORY + "/" + NORMALIZATION
|
||||
DESCRIPTION = ("Normalize the image to the ImageNet dataset")
|
||||
UNIQUE_NAME = "SET_NormalizeToImageNetDataset"
|
||||
DISPLAY_NAME = "Normalize Image to ImageNet"
|
||||
imagenet_normalize = None
|
||||
|
||||
def normalize(self, image: torch.Tensor):
|
||||
return (TF.normalize(image.permute(0, 3, 1, 2), # BHWC -> BCHW
|
||||
mean=[0.485, 0.456, 0.406],
|
||||
std=[0.229, 0.224, 0.225]).permute(0, 2, 3, 1),) # BCHW -> BHWC
|
||||
|
||||
|
||||
class NormalizeToRangeMinus05to05():
|
||||
"""
|
||||
A ComfyUI node to normalize the values to the [-0.5, 0.5] range
|
||||
"""
|
||||
@classmethod
|
||||
def INPUT_TYPES(cls):
|
||||
return {"required": {"image": ("IMAGE",), }, }
|
||||
RETURN_TYPES = ("IMAGE",)
|
||||
RETURN_NAMES = ("image",)
|
||||
FUNCTION = "normalize"
|
||||
CATEGORY = BASE_CATEGORY + "/" + NORMALIZATION
|
||||
DESCRIPTION = ("Normalize the image to [-0.5, 0.5]")
|
||||
UNIQUE_NAME = "SET_NormalizeToRangeMinus05to05"
|
||||
DISPLAY_NAME = "Normalize Image to [-0.5, 0.5]"
|
||||
imagenet_normalize = None
|
||||
|
||||
def normalize(self, image: torch.Tensor):
|
||||
return (TF.normalize(image.permute(0, 3, 1, 2), # BHWC -> BCHW
|
||||
mean=[0.5, 0.5, 0.5],
|
||||
std=[1.0, 1.0, 1.0]).permute(0, 2, 3, 1),) # BCHW -> BHWC
|
||||
|
||||
|
||||
class NormalizeToRangeMinus1to1():
|
||||
"""
|
||||
A ComfyUI node to normalize the values to the [-1, 1] range
|
||||
"""
|
||||
@classmethod
|
||||
def INPUT_TYPES(cls):
|
||||
return {"required": {"image": ("IMAGE",), }, }
|
||||
RETURN_TYPES = ("IMAGE",)
|
||||
RETURN_NAMES = ("image",)
|
||||
FUNCTION = "normalize"
|
||||
CATEGORY = BASE_CATEGORY + "/" + NORMALIZATION
|
||||
DESCRIPTION = ("Normalize the image to [-1, 1]")
|
||||
UNIQUE_NAME = "SET_NormalizeToRangeMinus1to1"
|
||||
DISPLAY_NAME = "Normalize Image to [-1, 1] (i.e. GAN)"
|
||||
imagenet_normalize = None
|
||||
|
||||
def normalize(self, image: torch.Tensor):
|
||||
return (TF.normalize(image.permute(0, 3, 1, 2), # BHWC -> BCHW
|
||||
mean=[0.5, 0.5, 0.5],
|
||||
std=[0.5, 0.5, 0.5]).permute(0, 2, 3, 1),) # BCHW -> BHWC
|
||||
|
||||
Reference in New Issue
Block a user