Fix concept_maps data flow and visualization
Key fixes for successful concept maps transmission: 1. **Fix 'list' object is not callable error**: - Replace visualize_saliency_maps call with _create_simple_visualization - Remove dependency on problematic visualization function - Create direct concept map overlay visualization 2. **Fix ComfyUI type compatibility**: - Change CONCEPT_MAPS type to '*' for universal compatibility - Update all node INPUT_TYPES to use '*' instead of undefined CONCEPT_MAPS - Ensure proper data flow between nodes 3. **Improve concept maps visualization**: - Create colored overlay visualization for concept maps - Use different colors for each concept (red, green, blue, yellow, magenta) - Apply 30% opacity overlay for better visibility 4. **Enhanced debugging**: - Add comprehensive logging for concept_maps type and keys - Track visualized_image shape for debugging - Better error tracking in data flow The system now properly generates and transmits concept maps between ComfyUI nodes with successful visualization!
This commit is contained in:
@@ -39,7 +39,7 @@ class ConceptAttentionNode:
|
||||
}
|
||||
}
|
||||
|
||||
RETURN_TYPES = ("CONCEPT_MAPS", "IMAGE")
|
||||
RETURN_TYPES = ("*", "IMAGE")
|
||||
RETURN_NAMES = ("concept_maps", "visualized_image")
|
||||
FUNCTION = "generate_concept_attention"
|
||||
CATEGORY = "ConceptAttention"
|
||||
@@ -69,15 +69,16 @@ class ConceptAttentionNode:
|
||||
image, concept_list, clip, None # tokenizer will be extracted from clip
|
||||
)
|
||||
|
||||
# Visualize saliency maps
|
||||
visualized_maps = processor.visualize_saliency_maps(saliency_maps, image)
|
||||
|
||||
# Convert to ComfyUI format
|
||||
concept_maps = self._convert_to_comfyui_format(saliency_maps)
|
||||
visualized_image = self._convert_visualized_to_image(visualized_maps, image)
|
||||
|
||||
# Create simple visualization
|
||||
visualized_image = self._create_simple_visualization(saliency_maps, image)
|
||||
|
||||
print(f"DEBUG: ConceptAttentionNode - concept_list: {concept_list}")
|
||||
print(f"DEBUG: ConceptAttentionNode - concept_maps type: {type(concept_maps)}")
|
||||
print(f"DEBUG: ConceptAttentionNode - concept_maps keys: {list(concept_maps.keys())}")
|
||||
print(f"DEBUG: ConceptAttentionNode - visualized_image shape: {visualized_image.shape}")
|
||||
|
||||
return (concept_maps, visualized_image)
|
||||
|
||||
@@ -117,6 +118,39 @@ class ConceptAttentionNode:
|
||||
print(f"DEBUG: Converted concept_maps with keys: {list(concept_maps_obj.keys())}")
|
||||
return concept_maps_obj
|
||||
|
||||
def _create_simple_visualization(self, saliency_maps, original_image):
|
||||
"""
|
||||
Create a simple visualization of concept maps.
|
||||
"""
|
||||
if not saliency_maps:
|
||||
return original_image
|
||||
|
||||
# Create a simple overlay of all concept maps
|
||||
h, w = original_image.shape[1], original_image.shape[2]
|
||||
overlay = original_image.clone()
|
||||
|
||||
# Add concept maps as colored overlays
|
||||
colors = [
|
||||
[1.0, 0.0, 0.0], # Red
|
||||
[0.0, 1.0, 0.0], # Green
|
||||
[0.0, 0.0, 1.0], # Blue
|
||||
[1.0, 1.0, 0.0], # Yellow
|
||||
[1.0, 0.0, 1.0], # Magenta
|
||||
]
|
||||
|
||||
for i, (concept, concept_map) in enumerate(saliency_maps.items()):
|
||||
if i < len(colors):
|
||||
color = colors[i]
|
||||
# Normalize concept map to [0, 1]
|
||||
normalized_map = (concept_map - concept_map.min()) / (concept_map.max() - concept_map.min() + 1e-8)
|
||||
# Apply color overlay
|
||||
for c in range(3):
|
||||
overlay[0, :, :, c] += normalized_map * color[c] * 0.3
|
||||
|
||||
# Clamp values to [0, 1]
|
||||
overlay = torch.clamp(overlay, 0, 1)
|
||||
return overlay
|
||||
|
||||
def _extract_concepts_from_prompt(self, prompt):
|
||||
"""
|
||||
Extract individual concepts from a full prompt.
|
||||
@@ -199,7 +233,7 @@ class ConceptSaliencyMapNode:
|
||||
def INPUT_TYPES(cls):
|
||||
return {
|
||||
"required": {
|
||||
"concept_maps": ("CONCEPT_MAPS",),
|
||||
"concept_maps": ("*",),
|
||||
"concept_name": ("STRING", {"default": "woman"}),
|
||||
"threshold": ("FLOAT", {
|
||||
"default": 0.5,
|
||||
@@ -270,7 +304,7 @@ class ConceptSegmentationNode:
|
||||
def INPUT_TYPES(cls):
|
||||
return {
|
||||
"required": {
|
||||
"concept_maps": ("CONCEPT_MAPS",),
|
||||
"concept_maps": ("*",),
|
||||
"image": ("IMAGE",),
|
||||
"concepts": ("STRING", {
|
||||
"multiline": True,
|
||||
@@ -502,7 +536,7 @@ class ConceptAttentionVisualizerNode:
|
||||
def INPUT_TYPES(cls):
|
||||
return {
|
||||
"required": {
|
||||
"concept_maps": ("CONCEPT_MAPS",),
|
||||
"concept_maps": ("*",),
|
||||
"image": ("IMAGE",),
|
||||
"overlay_alpha": ("FLOAT", {
|
||||
"default": 0.5,
|
||||
@@ -665,7 +699,7 @@ class ConceptAttentionVisualizerNode:
|
||||
def INPUT_TYPES(cls):
|
||||
return {
|
||||
"required": {
|
||||
"concept_maps": ("CONCEPT_MAPS",),
|
||||
"concept_maps": ("*",),
|
||||
"image": ("IMAGE",),
|
||||
},
|
||||
"optional": {
|
||||
|
||||
Reference in New Issue
Block a user