Files
ComfyUI/custom_nodes/controlaltai-nodes/region_overlay_visualizer_node.py
jaidaken f09734b0ee
Some checks failed
Python Linting / Run Ruff (push) Has been cancelled
Python Linting / Run Pylint (push) Has been cancelled
Full Comfy CI Workflow Runs / test-stable (12.1, , linux, 3.10, [self-hosted Linux], stable) (push) Has been cancelled
Full Comfy CI Workflow Runs / test-stable (12.1, , linux, 3.11, [self-hosted Linux], stable) (push) Has been cancelled
Full Comfy CI Workflow Runs / test-stable (12.1, , linux, 3.12, [self-hosted Linux], stable) (push) Has been cancelled
Full Comfy CI Workflow Runs / test-unix-nightly (12.1, , linux, 3.11, [self-hosted Linux], nightly) (push) Has been cancelled
Execution Tests / test (macos-latest) (push) Has been cancelled
Execution Tests / test (ubuntu-latest) (push) Has been cancelled
Execution Tests / test (windows-latest) (push) Has been cancelled
Test server launches without errors / test (push) Has been cancelled
Unit Tests / test (macos-latest) (push) Has been cancelled
Unit Tests / test (ubuntu-latest) (push) Has been cancelled
Unit Tests / test (windows-2022) (push) Has been cancelled
Add custom nodes, Civitai loras (LFS), and vast.ai setup script
Includes 30 custom nodes committed directly, 7 Civitai-exclusive
loras stored via Git LFS, and a setup script that installs all
dependencies and downloads HuggingFace-hosted models on vast.ai.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-09 00:56:42 +00:00

90 lines
2.9 KiB
Python

import torch
import numpy as np
from typing import Tuple
class RegionOverlayVisualizer:
@classmethod
def INPUT_TYPES(cls):
return {
"required": {
"image": ("IMAGE",),
"region_preview": ("IMAGE",),
"opacity": ("FLOAT", {
"default": 0.3,
"min": 0.0,
"max": 1.0,
"step": 0.1,
"display": "Overlay Opacity"
}),
}
}
RETURN_TYPES = ("IMAGE",)
FUNCTION = "visualize_regions"
CATEGORY = "ControlAltAI Nodes/Flux Region"
def visualize_regions(
self,
image: torch.Tensor,
region_preview: torch.Tensor,
opacity: float,
) -> Tuple[torch.Tensor]:
try:
print("\n=== Starting Region Overlay Visualization ===")
print(f"Initial shapes - Image: {image.shape}, Preview: {region_preview.shape}")
# Ensure input tensors are in [B, H, W, C] format
if len(image.shape) == 3:
image = image.unsqueeze(0)
if len(region_preview.shape) == 3:
region_preview = region_preview.unsqueeze(0)
# Get working copies
base_image = image.clone()
preview = region_preview.clone()
# Convert to numpy for mask creation (keeping batch and HWC format)
preview_np = (preview * 255).byte().cpu().numpy()
# Create mask based on preview content (operating on the last dimension - channels)
color_sum = np.sum(preview_np, axis=-1) # Sum across color channels
max_channel = np.max(preview_np, axis=-1)
min_channel = np.min(preview_np, axis=-1)
# Create binary mask where content exists
mask = (
(color_sum > 50) &
(max_channel > 30) &
((max_channel - min_channel) > 10)
)
# Expand mask to match input dimensions
mask = mask[..., None] # Add channel dimension back
mask = torch.from_numpy(mask).to(image.device)
print(f"Mask shape: {mask.shape}")
print(f"Masked pixels: {mask.sum().item()}/{mask.numel()} ({mask.sum().item()/mask.numel()*100:.2f}%)")
# Apply blending only where mask is True
result = torch.where(
mask.bool(),
(1 - opacity) * base_image + opacity * preview,
base_image
)
print(f"Final shape: {result.shape}")
return (result,)
except Exception as e:
print(f"Error in visualization: {str(e)}")
import traceback
traceback.print_exc()
return (image,)
NODE_CLASS_MAPPINGS = {
"RegionOverlayVisualizer": RegionOverlayVisualizer
}
NODE_DISPLAY_NAME_MAPPINGS = {
"RegionOverlayVisualizer": "Region Overlay Visualizer"
}