[Added] Arbitrary normalization and a node to input the parameters
This commit is contained in:
@@ -35,6 +35,8 @@ Currently we just have a few nodes used by other nodes I maintain.
|
||||
- [Normalize Image to ImageNet](docs/nodes_img.md#4-normalize-image-to-imagenet)
|
||||
- [Normalize Image to [-0.5, 0.5]](docs/nodes_img.md#5-normalize-image-to-05-05)
|
||||
- [Normalize Image to [-1, 1]](docs/nodes_img.md#6-normalize-image-to-1-1)
|
||||
- [Arbitrary Normalize](docs/nodes_img.md#14-arbitrary-normalize)
|
||||
- [Normalize Parameters](docs/nodes_img.md#15-normalize-parameters)
|
||||
- 📝 [Usage Notes](#-usage-notes)
|
||||
- 📜 [Project History](#-project-history)
|
||||
- ⚖️ [License](#️-license)
|
||||
|
||||
+33
-2
@@ -37,7 +37,7 @@
|
||||
- The animated frame is automatically resized to fit the bounding box dimensions before pasting. The pasting logic safely handles cases where the bbox is partially outside the image boundaries.
|
||||
|
||||
# 3. Face Composite (frame by frame)
|
||||
- **Display Name:** `"Face Composite (frame by frame)`
|
||||
- **Display Name:** `Face Composite (frame by frame)`
|
||||
- **Internal Name:** `SET_CompositeFaceFrameByFrame`
|
||||
- **Category:** `image/manipulation`
|
||||
- **Description:** This node is a simplified variant for **1-to-1** compositing. It is perfect for video processing workflows where you need to paste a sequence of processed frames back into the original video sequence at a static location.
|
||||
@@ -55,7 +55,7 @@
|
||||
|
||||
|
||||
# 4. Normalize Image to ImageNet
|
||||
- **Display Name:** `"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.
|
||||
@@ -255,3 +255,34 @@
|
||||
- `mask` (`MASK`): The resized mask tensor.
|
||||
- `width` (`INT`): The final width of the output mask.
|
||||
- `height` (`INT`): The final height of the output mask.
|
||||
|
||||
|
||||
# 14. Arbitrary Normalize
|
||||
- **Display Name:** `Arbitrary Normalize`
|
||||
- **Internal Name:** `SET_NormalizeArbitrary`
|
||||
- **Category:** `image/normalization`
|
||||
- **Description:** Normalizes an image tensor using the mean and standard deviation provided in the `parameters` input.
|
||||
- **Purpose:** Essential for pre-processing images before feeding them into models
|
||||
- **Inputs:**
|
||||
- `image` (`IMAGE`): A standard ComfyUI image tensor in the `[0, 1]` range.
|
||||
- `parameters` (`NORM_PARAMS`): The parameters for the normalization. This is a dict with two keys, `mean` and `std`, which are lists with the R, G, B parameters.
|
||||
- **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 values from NORM_PARAMS
|
||||
|
||||
|
||||
# 15. Normalize Parameters
|
||||
- **Display Name:** `Normalize Parameters`
|
||||
- **Internal Name:** `SET_NormalizeParameters`
|
||||
- **Category:** `image/normalization`
|
||||
- **Description:** Provides the `NORM_PARAMS` for the [Arbitrary Normalize](#14-arbitrary-normalize) node
|
||||
- **Purpose:** This is a user interface to the [Arbitrary Normalize](#14-arbitrary-normalize) node
|
||||
- **Inputs:**
|
||||
- `mean_red` (`FLOAT`): Mean value for the red channel
|
||||
- `mean_green` (`FLOAT`): Mean value for the green channel
|
||||
- `mean_blue` (`FLOAT`): Mean value for the blue channel
|
||||
- `std_red` (`FLOAT`): Standard deviation for the red channel
|
||||
- `std_green` (`FLOAT`): Standard deviation for the green channel
|
||||
- `std_blue` (`FLOAT`): Standard deviation for the blue channel
|
||||
- **Output:**
|
||||
- `parameters` (`NORM_PARAMS`): The parameters for the normalization. This is a dict with two keys, `mean` and `std`, which are lists with the R, G, B parameters.
|
||||
|
||||
+57
-3
@@ -89,6 +89,12 @@ PAD_TRANS = ("FLOAT", {
|
||||
"display": "number",
|
||||
"tooltip": ("The transparency for the padded area for all modes except `edge_pixel`."
|
||||
"1.0 is fully transparent, 0.0 is fully opaque.")})
|
||||
NORM_PARAM = ("FLOAT", {
|
||||
"default": 1.0,
|
||||
"min": 0.0,
|
||||
"max": 1.0,
|
||||
"step": 0.1,
|
||||
"display": "number"})
|
||||
|
||||
|
||||
def tensor_to_pil(tensor: torch.Tensor) -> Image.Image:
|
||||
@@ -418,7 +424,6 @@ class NormalizeToImageNetDataset():
|
||||
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
|
||||
@@ -440,7 +445,6 @@ class NormalizeToRangeMinus05to05():
|
||||
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
|
||||
@@ -462,7 +466,6 @@ class NormalizeToRangeMinus1to1():
|
||||
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
|
||||
@@ -470,6 +473,57 @@ class NormalizeToRangeMinus1to1():
|
||||
std=[0.5, 0.5, 0.5]).permute(0, 2, 3, 1),) # BCHW -> BHWC
|
||||
|
||||
|
||||
class NormalizeArbitrary():
|
||||
"""
|
||||
A ComfyUI node to normalize the values to arbitrary mean/std
|
||||
"""
|
||||
@classmethod
|
||||
def INPUT_TYPES(cls):
|
||||
return {
|
||||
"required": {
|
||||
"image": ("IMAGE",),
|
||||
"parameters": ("NORM_PARAMS",),
|
||||
},
|
||||
}
|
||||
RETURN_TYPES = ("IMAGE",)
|
||||
RETURN_NAMES = ("image",)
|
||||
FUNCTION = "normalize"
|
||||
CATEGORY = BASE_CATEGORY + "/" + NORMALIZATION
|
||||
DESCRIPTION = ("Normalize the image to the provided parameters")
|
||||
UNIQUE_NAME = "SET_NormalizeArbitrary"
|
||||
DISPLAY_NAME = "Arbitrary Normalize"
|
||||
|
||||
def normalize(self, image: torch.Tensor, parameters):
|
||||
return (TF.normalize(image.movedim(-1, 1), # BHWC -> BCHW
|
||||
mean=parameters["mean"],
|
||||
std=parameters["std"]).movedim(1, -1),) # BCHW -> BHWC
|
||||
|
||||
|
||||
class NormalizeParameters():
|
||||
@classmethod
|
||||
def INPUT_TYPES(cls):
|
||||
return {
|
||||
"required": {
|
||||
"mean_red": NORM_PARAM,
|
||||
"mean_green": NORM_PARAM,
|
||||
"mean_blue": NORM_PARAM,
|
||||
"std_red": NORM_PARAM,
|
||||
"std_green": NORM_PARAM,
|
||||
"std_blue": NORM_PARAM,
|
||||
},
|
||||
}
|
||||
RETURN_TYPES = ("NORM_PARAMS",)
|
||||
RETURN_NAMES = ("parameters",)
|
||||
FUNCTION = "normalize"
|
||||
CATEGORY = BASE_CATEGORY + "/" + NORMALIZATION
|
||||
DESCRIPTION = ("Parameters for the arbitrary normalization")
|
||||
UNIQUE_NAME = "SET_NormalizeParameters"
|
||||
DISPLAY_NAME = "Normalize Parameters"
|
||||
|
||||
def normalize(self, mean_red, mean_green, mean_blue, std_red, std_green, std_blue):
|
||||
return ({"mean": [mean_red, mean_green, mean_blue], "std": [std_red, std_green, std_blue]},)
|
||||
|
||||
|
||||
class ApplyMaskAFFCE:
|
||||
@classmethod
|
||||
def INPUT_TYPES(cls):
|
||||
|
||||
Reference in New Issue
Block a user