Files
slahiriandClaude Opus 4.5 786926982f feat: add scene/landmark/sky taggers, improve wildlife detection, add progress bar
New Taggers:
- LandmarkTagger: 150+ famous landmarks (monuments, natural wonders, bridges)
- SkyWeatherTagger: clouds, sun/moon, weather, celestial elements
- Places365Tagger: scene recognition with 365 categories
- CLIPSceneTagger: photo style, camera type, subject, mood
- WildlifeTagger: animals, pets, nature, biomes

Scene Detection Improvements:
- Fixed "no humans" tag override for human detection
- Fixed scene type detection for animal/wildlife photos
- Wildlife/landscape taggers now skip for portrait/fashion scenes
- Canonical structurer respects "no humans" + "animal" tags

Analysis Node Improvements:
- Added analysis_enabled toggle (skip taggers for quick caption)
- Added prompt output (florence_description)
- Progress bar now starts during taggers phase
- Progress callback passed through pipeline

Bug Fixes:
- Fixed abstract method error in Places365/CLIPScene/Wildlife taggers
- Added load() method to new CLIP-based taggers

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-28 03:48:10 +05:30

142 lines
3.9 KiB
Python

# -*- coding: utf-8 -*-
"""
SID Photography Toolkit v5.0
AI-powered image captioning for ComfyUI.
Clean, modular architecture with plug-and-play models.
Author: Siddhartha Lahiri
License: MIT
"""
__version__ = "5.0.0"
# Import nodes
from .nodes import (
SID_ImageAnalysis,
SID_PromptSynthesis,
SID_PromptCompose,
)
# V1 API registration
NODE_CLASS_MAPPINGS = {
"SID_ImageAnalysis": SID_ImageAnalysis,
"SID_PromptSynthesis": SID_PromptSynthesis,
"SID_PromptCompose": SID_PromptCompose,
}
NODE_DISPLAY_NAME_MAPPINGS = {
"SID_ImageAnalysis": "SID Image Analysis",
"SID_PromptSynthesis": "SID Prompt Synthesis",
"SID_PromptCompose": "SID Prompt Compose",
}
__all__ = ["NODE_CLASS_MAPPINGS", "NODE_DISPLAY_NAME_MAPPINGS"]
# Auto-install dependencies
def _install_dependencies():
"""Auto-install required dependencies at startup."""
import subprocess
import sys
# Required packages: (import_name, pip_package)
required = [
("yaml", "pyyaml"),
("onnxruntime", "onnxruntime-gpu"),
("cv2", "opencv-python"),
("timm", "timm"),
("huggingface_hub", "huggingface_hub"),
]
# Optional packages
optional = [
("nudenet", "nudenet"),
("pyiqa", "pyiqa"),
("ultralytics", "ultralytics"),
("imgutils", "dghs-imgutils>=0.19.0"),
]
def is_installed(module_name):
try:
__import__(module_name)
return True
except ImportError:
return False
def install(package, quiet=True):
print(f"[AI-Photo-Toolkit] Installing {package}...")
try:
cmd = [sys.executable, "-m", "pip", "install", package]
if quiet:
cmd.append("-q")
subprocess.check_call(cmd, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
else:
# Show output for debugging
subprocess.check_call(cmd)
return True
except subprocess.CalledProcessError as e:
# Try without GPU for onnxruntime
if package == "onnxruntime-gpu":
print(f"[AI-Photo-Toolkit] GPU version failed, trying CPU...")
try:
subprocess.check_call(
[sys.executable, "-m", "pip", "install", "onnxruntime", "-q"],
stdout=subprocess.DEVNULL,
stderr=subprocess.DEVNULL,
)
return True
except subprocess.CalledProcessError:
pass
print(f"[AI-Photo-Toolkit] Failed to install {package}: {e}")
return False
except Exception as e:
print(f"[AI-Photo-Toolkit] Error installing {package}: {e}")
return False
# Install required
for module, package in required:
if not is_installed(module):
install(package)
# Install optional (show output for debugging)
for module, package in optional:
if not is_installed(module):
install(package, quiet=False)
# Startup
def _print_startup():
print(f"\n[AI-Photo-Toolkit] v{__version__} loading...")
# Auto-install missing deps
_install_dependencies()
# Check what's available now
available = []
missing = []
checks = [
("onnxruntime", "WD14, JoyTag"),
("cv2", "Photography, Composition"),
("timm", "Fashion"),
("nudenet", "NudeNet"),
("pyiqa", "IQA"),
("ultralytics", "YOLOv8"),
("imgutils", "PixAI"),
]
for module, taggers in checks:
try:
__import__(module)
available.append(taggers)
except ImportError:
missing.append(taggers)
print(f"[AI-Photo-Toolkit] v{__version__} ready!")
print(f"[AI-Photo-Toolkit] Available: {', '.join(available)}")
if missing:
print(f"[AI-Photo-Toolkit] Unavailable: {', '.join(missing)}")
print()
_print_startup()