first commit

This commit is contained in:
sumitchatterjee13
2025-09-20 23:40:01 +10:00
commit 0ff1caa426
9 changed files with 979 additions and 0 deletions
+139
View File
@@ -0,0 +1,139 @@
# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]
*$py.class
# C extensions
*.so
# Distribution / packaging
.Python
build/
develop-eggs/
dist/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
var/
wheels/
*.egg-info/
.installed.cfg
*.egg
MANIFEST
# PyInstaller
# Usually these files are written by a python script from a template
# before PyInstaller builds the exe, so as to inject date/other infos into it.
*.manifest
*.spec
# Installer logs
pip-log.txt
pip-delete-this-directory.txt
# Unit test / coverage reports
htmlcov/
.tox/
.nox/
.coverage
.coverage.*
.cache
nosetests.xml
coverage.xml
*.cover
.hypothesis/
.pytest_cache/
# Translations
*.mo
*.pot
# Django stuff:
*.log
local_settings.py
db.sqlite3
# Flask stuff:
instance/
.webassets-cache
# Scrapy stuff:
.scrapy
# Sphinx documentation
docs/_build/
# PyBuilder
target/
# Jupyter Notebook
.ipynb_checkpoints
# IPython
profile_default/
ipython_config.py
# pyenv
.python-version
# celery beat schedule file
celerybeat-schedule
# SageMath parsed files
*.sage.py
# Environments
.env
.venv
env/
venv/
ENV/
env.bak/
venv.bak/
# Spyder project settings
.spyderproject
.spyproject
# Rope project settings
.ropeproject
# mkdocs documentation
/site
# mypy
.mypy_cache/
.dmypy.json
dmypy.json
# Pyre type checker
.pyre/
# IDEs
.vscode/
.idea/
*.swp
*.swo
*~
# OS generated files
.DS_Store
.DS_Store?
._*
.Spotlight-V100
.Trashes
ehthumbs.db
Thumbs.db
# ComfyUI specific
test_outputs/
temp_images/
*.tmp
# Development files
dev_test.py
scratch.py
+61
View File
@@ -0,0 +1,61 @@
# Changelog
All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## [Unreleased]
### Added
- Nothing yet
### Changed
- Nothing yet
### Fixed
- Nothing yet
## [1.0.0] - 2025-01-20
### Added
- **Luminance Stack Processor (3 Stops)** - Professional HDR processing node for merging EV+2, EV+0, EV-2 exposures
- **Luminance Stack Processor (5 Stops)** - Professional HDR processing node for merging EV+4, EV+2, EV+0, EV-2, EV-4 exposures
- **Debevec Algorithm Implementation** - Industry-standard HDR reconstruction using Paul Debevec's method
- **16-bit Output Support** - Maximum dynamic range preservation in final images
- **Automatic Camera Response Function Estimation** - Intelligent sensor response curve calculation
- **Configurable Exposure Steps** - Adjustable EV step sizes for different capture methods
- **Error Handling & Fallbacks** - Graceful degradation with middle exposure fallback
- **Professional Documentation** - Complete README, installation guide, and usage examples
- **Modern Python Packaging** - Full pyproject.toml configuration with semantic versioning
- **Comprehensive Testing** - Unit tests for core HDR processing functionality
- **ComfyUI Integration** - Seamless tensor format handling and node registration
### Technical Features
- OpenCV-based HDR processing pipeline
- Automatic image alignment preparation
- Memory-efficient processing with cleanup
- Detailed logging for debugging
- Cross-platform compatibility (Windows, Linux, macOS)
### Dependencies
- OpenCV >= 4.8.0 (only external dependency)
- NumPy and PyTorch provided by ComfyUI
- Python 3.8+ support
---
## Version Numbering
This project follows [Semantic Versioning](https://semver.org/):
- **MAJOR** version when you make incompatible API changes
- **MINOR** version when you add functionality in a backward compatible manner
- **PATCH** version when you make backward compatible bug fixes
### Version History Guidelines
- **1.x.x** - Stable production releases with Debevec HDR algorithm
- **0.x.x** - Pre-release/beta versions (not used in this project)
- **x.x.0** - Major feature releases
- **x.x.1+** - Bug fixes and minor improvements
+21
View File
@@ -0,0 +1,21 @@
MIT License
Copyright (c) 2025 Luminance Stack Processor Contributors
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
+224
View File
@@ -0,0 +1,224 @@
# Luminance Stack Processor - ComfyUI Custom Nodes
[![Version](https://img.shields.io/badge/version-1.0.0-blue.svg)](https://github.com/sumitchatterjee13/Luminance-Stack-Processor)
[![Python](https://img.shields.io/badge/python-3.8+-blue.svg)](https://python.org)
[![License](https://img.shields.io/badge/license-MIT-green.svg)](https://github.com/sumitchatterjee13/Luminance-Stack-Processor/blob/main/LICENSE)
[![ComfyUI](https://img.shields.io/badge/ComfyUI-compatible-orange.svg)](https://github.com/comfyanonymous/ComfyUI)
[![GitHub](https://img.shields.io/badge/GitHub-Repository-black.svg)](https://github.com/sumitchatterjee13/Luminance-Stack-Processor)
Professional HDR (High Dynamic Range) processing nodes for ComfyUI using the **Debevec Algorithm** for merging multiple exposure images into a single high dynamic range image.
**Version: 1.0.0** | **Release Date: 2025-01-20**
## 🎯 Features
- **Professional HDR Processing**: Implements the industry-standard Debevec Algorithm for HDR image creation
- **Two Processing Modes**:
- **3-Stop Processor**: Merges EV+2, EV+0, EV-2 exposures
- **5-Stop Processor**: Merges EV+4, EV+2, EV+0, EV-2, EV-4 exposures
- **16-bit Output**: Preserves maximum dynamic range in the final image
- **Automatic Camera Response Function**: Estimates and applies camera response curves
- **Fallback Safety**: Gracefully handles errors with fallback to middle exposure
- **ComfyUI Integration**: Seamless integration with ComfyUI workflows
## 📋 Requirements
- ComfyUI
- Python 3.8+
- OpenCV (cv2) >= 4.8.0
- NumPy >= 1.21.0
- PyTorch >= 1.9.0
## 🚀 Installation
1. **Clone or Download** this repository to your ComfyUI custom nodes directory:
```bash
# Method 1: Clone directly into ComfyUI custom nodes directory
cd ComfyUI/custom_nodes/
git clone https://github.com/sumitchatterjee13/Luminance-Stack-Processor.git luminance-stack-processor
# Method 2: Download ZIP and extract to:
# ComfyUI/custom_nodes/luminance-stack-processor/
```
2. **Install Dependencies**:
```bash
pip install -r requirements.txt
```
Or install manually:
```bash
pip install opencv-python>=4.8.0 numpy>=1.21.0 torch>=1.9.0
```
3. **Restart ComfyUI** to load the new nodes
## 🎨 Usage
### Luminance Stack Processor (3 Stops)
Perfect for standard HDR bracketing with 3 exposures:
**Inputs:**
- `ev_plus_2`: Overexposed image (+2 EV)
- `ev_0`: Normal exposure image (0 EV)
- `ev_minus_2`: Underexposed image (-2 EV)
- `exposure_step`: (Optional) EV step size (default: 2.0)
**Output:**
- `hdr_image`: Merged 16-bit HDR image
### Luminance Stack Processor (5 Stops)
For extended dynamic range with 5 exposures:
**Inputs:**
- `ev_plus_4`: Most overexposed image (+4 EV)
- `ev_plus_2`: Overexposed image (+2 EV)
- `ev_0`: Normal exposure image (0 EV)
- `ev_minus_2`: Underexposed image (-2 EV)
- `ev_minus_4`: Most underexposed image (-4 EV)
- `exposure_step`: (Optional) EV step size (default: 2.0)
**Output:**
- `hdr_image`: Merged 16-bit HDR image
## 🔬 How It Works
The nodes implement the **Debevec Algorithm** (Paul E. Debevec, Jitendra Malik, 1997) which:
1. **Analyzes Multiple Exposures**: Takes differently exposed images of the same scene
2. **Estimates Camera Response Function**: Determines how the camera sensor responds to light
3. **Recovers Scene Radiance**: Calculates the actual light values in the scene
4. **Merges to HDR**: Combines all exposures into a single high dynamic range image
5. **Tone Maps for Output**: Converts to 16-bit format for maximum compatibility
## 📸 Best Practices
### For Capturing Source Images:
- Use a **tripod** for perfect alignment
- Keep the **same white balance** across all exposures
- Use **manual focus** to prevent focus shifts
- Capture in **RAW format** when possible
- Use **exposure compensation** or **manual mode**
### EV (Exposure Value) Guidelines:
- **3-Stop**: +2, 0, -2 EV (4x range)
- **5-Stop**: +4, +2, 0, -2, -4 EV (16x range)
- Adjust `exposure_step` parameter if using different increments
## ⚙️ Technical Details
- **Algorithm**: Debevec & Malik HDR reconstruction
- **Input Format**: ComfyUI IMAGE tensors (0-1 float range)
- **Output Format**: 16-bit images for extended dynamic range
- **Processing**: OpenCV's `createCalibrateDebevec()` and `createMergeDebevec()`
- **Memory**: Efficient processing with automatic cleanup
- **Error Handling**: Graceful fallbacks with detailed logging
## 🔧 Troubleshooting
### Common Issues:
1. **"Module not found" error**:
- Ensure all dependencies are installed: `pip install -r requirements.txt`
- Restart ComfyUI completely
2. **Poor HDR results**:
- Ensure input images are properly exposed (not all over/under)
- Check that images are aligned (use tripod)
- Verify EV differences match your capture method
3. **Memory issues**:
- Process smaller images first
- Ensure adequate RAM available
- Close unnecessary applications
### Debug Information:
The nodes provide detailed logging. Check your ComfyUI console for processing information and error details.
## 🏗️ Development
### Project Structure:
```
luminance-stack-processor/
├── __init__.py # ComfyUI registration
├── luminance_stack_processor.py # Main node implementations
├── requirements.txt # Dependencies
└── README.md # Documentation
```
### Contributing:
1. Fork the repository
2. Create a feature branch
3. Test with various HDR image sets
4. Submit a pull request
## 📝 Changelog
See [CHANGELOG.md](CHANGELOG.md) for version history and detailed release notes.
## 🔧 Development
### Version Management
This project uses [Semantic Versioning](https://semver.org/). To bump version:
```bash
# Install bumpversion
pip install bump2version
# Bump patch version (1.0.0 -> 1.0.1)
bump2version patch
# Bump minor version (1.0.0 -> 1.1.0)
bump2version minor
# Bump major version (1.0.0 -> 2.0.0)
bump2version major
```
### Project Structure
```
luminance-stack-processor/
├── __init__.py # ComfyUI node registration & version info
├── luminance_stack_processor.py # Main HDR processing nodes
├── version.py # Centralized version management
├── pyproject.toml # Modern Python packaging configuration
├── requirements.txt # Runtime dependencies
├── README.md # Documentation
└── CHANGELOG.md # Version history
```
## 📚 References
- **Debevec, P. E., & Malik, J.** (1997). Recovering high dynamic range radiance maps from photographs. *ACM SIGGRAPH Computer Graphics*, 31(Annual Conference Series), 367-378.
- **OpenCV HDR Documentation**: https://docs.opencv.org/4.x/d3/db7/tutorial_hdr_imaging.html
- **ComfyUI Custom Node Guidelines**: https://docs.comfy.org/custom-nodes/
- **Semantic Versioning**: https://semver.org/
## 📜 License
MIT License - Feel free to use and modify for your projects.
## 🤝 Support
For issues, questions, or contributions:
- **GitHub Issues**: [Report bugs or request features](https://github.com/sumitchatterjee13/Luminance-Stack-Processor/issues)
- **GitHub Discussions**: [Ask questions or share workflows](https://github.com/sumitchatterjee13/Luminance-Stack-Processor/discussions)
- Check the troubleshooting section above
- Review ComfyUI console logs for detailed error information
- Check [CHANGELOG.md](CHANGELOG.md) for version-specific issues
- Ensure all dependencies are properly installed
### Contributing
We welcome contributions! Please:
1. Fork the repository
2. Create a feature branch (`git checkout -b feature/amazing-feature`)
3. Commit your changes (`git commit -m 'Add some amazing feature'`)
4. Push to the branch (`git push origin feature/amazing-feature`)
5. Open a Pull Request
---
**Happy HDR Processing!** 📸✨ | **Version 1.0.0**
+79
View File
@@ -0,0 +1,79 @@
"""
Luminance Stack Processor - ComfyUI Custom Nodes
Professional HDR processing nodes using the Debevec Algorithm
This module provides two custom nodes for ComfyUI:
1. Luminance Stack Processor (3 Stops) - For processing EV+2, EV+0, EV-2 exposures
2. Luminance Stack Processor (5 Stops) - For processing EV+4, EV+2, EV+0, EV-2, EV-4 exposures
Requirements:
- OpenCV (cv2)
- NumPy
- PyTorch
Installation:
1. Place this folder in your ComfyUI/custom_nodes/ directory
2. Install required dependencies: pip install opencv-python numpy torch
3. Restart ComfyUI
Author: Sumit Chatterjee
Version: 1.0.0
License: MIT
"""
import os
import sys
# Import version information
try:
from .version import __version__, get_version_string, get_full_version_info
except ImportError:
__version__ = "1.0.0"
get_version_string = lambda: f"v{__version__}"
get_full_version_info = lambda: {"version": __version__}
# Add current directory to Python path for imports
current_dir = os.path.dirname(os.path.realpath(__file__))
if current_dir not in sys.path:
sys.path.insert(0, current_dir)
try:
# Import the node classes
from .luminance_stack_processor import (
LuminanceStackProcessor3Stops,
LuminanceStackProcessor5Stops,
NODE_CLASS_MAPPINGS as NODES,
NODE_DISPLAY_NAME_MAPPINGS as DISPLAY_NAMES
)
# Export the mappings that ComfyUI expects
NODE_CLASS_MAPPINGS = NODES
NODE_DISPLAY_NAME_MAPPINGS = DISPLAY_NAMES
print("✅ Luminance Stack Processor nodes loaded successfully!")
print(f" - Version: {get_version_string()}")
print(f" - Available nodes: {list(NODE_CLASS_MAPPINGS.keys())}")
except ImportError as e:
print(f"❌ Failed to import Luminance Stack Processor nodes: {e}")
print(" Please ensure all required dependencies are installed:")
print(" pip install opencv-python numpy torch")
# Provide empty mappings to prevent ComfyUI errors
NODE_CLASS_MAPPINGS = {}
NODE_DISPLAY_NAME_MAPPINGS = {}
except Exception as e:
print(f"❌ Unexpected error loading Luminance Stack Processor nodes: {e}")
NODE_CLASS_MAPPINGS = {}
NODE_DISPLAY_NAME_MAPPINGS = {}
# Metadata for ComfyUI
__all__ = [
'NODE_CLASS_MAPPINGS',
'NODE_DISPLAY_NAME_MAPPINGS',
'__version__'
]
# Version info for external access
__version__ = __version__
+286
View File
@@ -0,0 +1,286 @@
"""
Luminance Stack Processor - Professional ComfyUI Custom Nodes
Implements HDR processing using the Debevec Algorithm for multiple exposure fusion
Author: Sumit Chatterjee
Version: 1.0.0
Semantic Versioning: MAJOR.MINOR.PATCH
"""
import numpy as np
import torch
import cv2
from typing import Tuple, List
import logging
# Set up logging
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)
def tensor_to_cv2(tensor: torch.Tensor) -> np.ndarray:
"""Convert ComfyUI tensor to OpenCV format"""
# ComfyUI tensors are typically [B, H, W, C] in 0-1 range
if len(tensor.shape) == 4:
tensor = tensor.squeeze(0) # Remove batch dimension
# Convert to numpy and scale to 0-255
image = tensor.cpu().numpy()
if image.dtype == np.float32 or image.dtype == np.float64:
image = np.clip(image * 255.0, 0, 255).astype(np.uint8)
return image
def cv2_to_tensor(image: np.ndarray) -> torch.Tensor:
"""Convert OpenCV image to ComfyUI tensor format"""
# Ensure image is float32 in 0-1 range
if image.dtype == np.uint8:
image = image.astype(np.float32) / 255.0
elif image.dtype == np.uint16:
image = image.astype(np.float32) / 65535.0
elif image.dtype == np.float32:
image = np.clip(image, 0.0, 1.0)
# Add batch dimension and convert to tensor
tensor = torch.from_numpy(image).unsqueeze(0)
return tensor
class DebevecHDRProcessor:
"""Core HDR processing using Debevec Algorithm"""
def __init__(self):
self.calibrator = cv2.createCalibrateDebevec()
self.merge_debevec = cv2.createMergeDebevec()
def process_hdr(self, images: List[np.ndarray], exposure_times: List[float]) -> np.ndarray:
"""
Process multiple exposure images using Debevec algorithm
Args:
images: List of images (OpenCV format)
exposure_times: List of exposure times in seconds
Returns:
HDR merged image as 16-bit
"""
try:
# Ensure images are in uint8 format for calibration
processed_images = []
for img in images:
if img.dtype != np.uint8:
if img.dtype == np.float32:
img = np.clip(img * 255.0, 0, 255).astype(np.uint8)
else:
img = img.astype(np.uint8)
processed_images.append(img)
# Convert exposure times to numpy array
times = np.array(exposure_times, dtype=np.float32)
logger.info(f"Processing {len(processed_images)} images with exposure times: {times}")
# Estimate camera response function
response = self.calibrator.process(processed_images, times)
# Merge images into HDR
hdr = self.merge_debevec.process(processed_images, times, response)
# Convert HDR to 16-bit for better dynamic range preservation
# Apply tone mapping to fit into 16-bit range
hdr_normalized = cv2.normalize(hdr, None, 0, 65535, cv2.NORM_MINMAX)
hdr_16bit = hdr_normalized.astype(np.uint16)
logger.info(f"HDR processing completed. Output shape: {hdr_16bit.shape}")
return hdr_16bit
except Exception as e:
logger.error(f"HDR processing error: {str(e)}")
# Fallback: return the middle exposure image
if images:
middle_idx = len(images) // 2
fallback = images[middle_idx]
if fallback.dtype != np.uint16:
fallback = (fallback.astype(np.float32) * 257).astype(np.uint16)
return fallback
raise e
class LuminanceStackProcessor3Stops:
"""
Professional ComfyUI Custom Node for 3-stop HDR processing
Processes EV+2, EV+0, EV-2 exposures using Debevec Algorithm
"""
@classmethod
def INPUT_TYPES(cls):
return {
"required": {
"ev_plus_2": ("IMAGE",),
"ev_0": ("IMAGE",),
"ev_minus_2": ("IMAGE",),
},
"optional": {
"exposure_step": ("FLOAT", {
"default": 2.0,
"min": 0.5,
"max": 5.0,
"step": 0.1,
"display": "number"
}),
}
}
RETURN_TYPES = ("IMAGE",)
RETURN_NAMES = ("hdr_image",)
FUNCTION = "process_3_stop_hdr"
CATEGORY = "image/luminance"
def __init__(self):
self.processor = DebevecHDRProcessor()
def process_3_stop_hdr(self, ev_plus_2, ev_0, ev_minus_2, exposure_step=2.0):
"""
Process 3-stop HDR merge
Args:
ev_plus_2: Overexposed image (+2 EV)
ev_0: Normal exposure image (0 EV)
ev_minus_2: Underexposed image (-2 EV)
exposure_step: EV step size
Returns:
Tuple containing merged HDR image
"""
try:
# Convert tensors to OpenCV format
img_plus_2 = tensor_to_cv2(ev_plus_2)
img_0 = tensor_to_cv2(ev_0)
img_minus_2 = tensor_to_cv2(ev_minus_2)
# Calculate exposure times based on EV values
# EV difference formula: time = base_time * 2^(-EV_difference)
base_time = 1.0 / 60.0 # 1/60s as base exposure
time_plus_2 = base_time * (2.0 ** (-exposure_step)) # Shorter time (overexposed)
time_0 = base_time # Normal exposure
time_minus_2 = base_time * (2.0 ** exposure_step) # Longer time (underexposed)
images = [img_plus_2, img_0, img_minus_2]
times = [time_plus_2, time_0, time_minus_2]
logger.info(f"3-Stop HDR: Processing with times {times}")
# Process HDR
hdr_result = self.processor.process_hdr(images, times)
# Convert back to tensor
output_tensor = cv2_to_tensor(hdr_result)
return (output_tensor,)
except Exception as e:
logger.error(f"3-Stop HDR processing failed: {str(e)}")
# Return middle exposure as fallback
return (ev_0,)
class LuminanceStackProcessor5Stops:
"""
Professional ComfyUI Custom Node for 5-stop HDR processing
Processes EV+4, EV+2, EV+0, EV-2, EV-4 exposures using Debevec Algorithm
"""
@classmethod
def INPUT_TYPES(cls):
return {
"required": {
"ev_plus_4": ("IMAGE",),
"ev_plus_2": ("IMAGE",),
"ev_0": ("IMAGE",),
"ev_minus_2": ("IMAGE",),
"ev_minus_4": ("IMAGE",),
},
"optional": {
"exposure_step": ("FLOAT", {
"default": 2.0,
"min": 0.5,
"max": 5.0,
"step": 0.1,
"display": "number"
}),
}
}
RETURN_TYPES = ("IMAGE",)
RETURN_NAMES = ("hdr_image",)
FUNCTION = "process_5_stop_hdr"
CATEGORY = "image/luminance"
def __init__(self):
self.processor = DebevecHDRProcessor()
def process_5_stop_hdr(self, ev_plus_4, ev_plus_2, ev_0, ev_minus_2, ev_minus_4, exposure_step=2.0):
"""
Process 5-stop HDR merge
Args:
ev_plus_4: Most overexposed image (+4 EV)
ev_plus_2: Overexposed image (+2 EV)
ev_0: Normal exposure image (0 EV)
ev_minus_2: Underexposed image (-2 EV)
ev_minus_4: Most underexposed image (-4 EV)
exposure_step: EV step size
Returns:
Tuple containing merged HDR image
"""
try:
# Convert tensors to OpenCV format
img_plus_4 = tensor_to_cv2(ev_plus_4)
img_plus_2 = tensor_to_cv2(ev_plus_2)
img_0 = tensor_to_cv2(ev_0)
img_minus_2 = tensor_to_cv2(ev_minus_2)
img_minus_4 = tensor_to_cv2(ev_minus_4)
# Calculate exposure times based on EV values
base_time = 1.0 / 60.0 # 1/60s as base exposure
time_plus_4 = base_time * (2.0 ** (-2 * exposure_step))
time_plus_2 = base_time * (2.0 ** (-exposure_step))
time_0 = base_time
time_minus_2 = base_time * (2.0 ** exposure_step)
time_minus_4 = base_time * (2.0 ** (2 * exposure_step))
images = [img_plus_4, img_plus_2, img_0, img_minus_2, img_minus_4]
times = [time_plus_4, time_plus_2, time_0, time_minus_2, time_minus_4]
logger.info(f"5-Stop HDR: Processing with times {times}")
# Process HDR
hdr_result = self.processor.process_hdr(images, times)
# Convert back to tensor
output_tensor = cv2_to_tensor(hdr_result)
return (output_tensor,)
except Exception as e:
logger.error(f"5-Stop HDR processing failed: {str(e)}")
# Return middle exposure as fallback
return (ev_0,)
# Node class mappings for ComfyUI
NODE_CLASS_MAPPINGS = {
"LuminanceStackProcessor3Stops": LuminanceStackProcessor3Stops,
"LuminanceStackProcessor5Stops": LuminanceStackProcessor5Stops,
}
# Display names for nodes in ComfyUI interface
NODE_DISPLAY_NAME_MAPPINGS = {
"LuminanceStackProcessor3Stops": "Luminance Stack Processor (3 Stops)",
"LuminanceStackProcessor5Stops": "Luminance Stack Processor (5 Stops)",
}
+115
View File
@@ -0,0 +1,115 @@
[build-system]
requires = ["setuptools>=65.0", "wheel"]
build-backend = "setuptools.build_meta"
[project]
name = "luminance-stack-processor"
version = "1.0.0"
description = "Professional HDR processing nodes for ComfyUI using the Debevec Algorithm"
readme = "README.md"
license = { text = "MIT" }
authors = [
{ name = "Sumit Chatterjee", email = "sumitchatterjee13@gmail.com" }
]
keywords = [
"comfyui",
"custom-node",
"hdr",
"image-processing",
"debevec-algorithm",
"exposure-fusion",
"computer-vision"
]
classifiers = [
"Development Status :: 5 - Production/Stable",
"Intended Audience :: Developers",
"Intended Audience :: End Users/Desktop",
"License :: OSI Approved :: MIT License",
"Operating System :: OS Independent",
"Programming Language :: Python :: 3",
"Programming Language :: Python :: 3.8",
"Programming Language :: Python :: 3.9",
"Programming Language :: Python :: 3.10",
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Topic :: Multimedia :: Graphics :: Graphics Conversion",
"Topic :: Scientific/Engineering :: Image Processing",
"Topic :: Software Development :: Libraries :: Python Modules"
]
requires-python = ">=3.8"
dependencies = [
"opencv-python>=4.8.0",
]
[project.optional-dependencies]
dev = [
"pytest>=6.0.0",
"black>=21.0.0",
"flake8>=3.9.0",
"mypy>=0.910"
]
enhanced = [
"opencv-contrib-python>=4.8.0"
]
[project.urls]
"Homepage" = "https://github.com/sumitchatterjee13/Luminance-Stack-Processor"
"Bug Reports" = "https://github.com/sumitchatterjee13/Luminance-Stack-Processor/issues"
"Source" = "https://github.com/sumitchatterjee13/Luminance-Stack-Processor"
"Documentation" = "https://github.com/sumitchatterjee13/Luminance-Stack-Processor/blob/main/README.md"
"Discussions" = "https://github.com/sumitchatterjee13/Luminance-Stack-Processor/discussions"
"Changelog" = "https://github.com/sumitchatterjee13/Luminance-Stack-Processor/blob/main/CHANGELOG.md"
[tool.setuptools.packages.find]
where = ["."]
include = ["luminance_stack_processor*"]
[tool.setuptools.package-data]
"*" = ["*.md", "*.txt", "*.toml"]
# Version management
[tool.bumpversion]
current_version = "1.0.0"
parse = "(?P<major>\\d+)\\.(?P<minor>\\d+)\\.(?P<patch>\\d+)"
serialize = ["{major}.{minor}.{patch}"]
search = "{current_version}"
replace = "{new_version}"
[[tool.bumpversion.files]]
filename = "version.py"
search = '__version__ = "{current_version}"'
replace = '__version__ = "{new_version}"'
[[tool.bumpversion.files]]
filename = "pyproject.toml"
search = 'version = "{current_version}"'
replace = 'version = "{new_version}"'
[[tool.bumpversion.files]]
filename = "README.md"
search = "Version: {current_version}"
replace = "Version: {new_version}"
# Code formatting
[tool.black]
line-length = 100
target-version = ['py38', 'py39', 'py310', 'py311', 'py312']
include = '\.pyi?$'
extend-exclude = '''
/(
# directories
\.eggs
| \.git
| \.hg
| \.mypy_cache
| \.tox
| \.venv
| build
| dist
)/
'''
[tool.isort]
profile = "black"
line_length = 100
+18
View File
@@ -0,0 +1,18 @@
# Luminance Stack Processor - ComfyUI Custom Nodes
# Required dependencies for HDR processing using Debevec Algorithm
# Core dependency for HDR processing
opencv-python>=4.8.0
# Optional but recommended for better performance
opencv-contrib-python>=4.8.0
# Development dependencies (optional)
# pytest>=6.0.0
# black>=21.0.0
# flake8>=3.9.0
# Notes:
# - NumPy and PyTorch are provided by ComfyUI, no need to install separately
# - Only OpenCV is required for the Debevec HDR algorithm implementation
# - If you encounter issues, try: pip install opencv-python --upgrade
+36
View File
@@ -0,0 +1,36 @@
"""
Version information for Luminance Stack Processor
"""
__version__ = "1.0.0"
__version_info__ = (1, 0, 0)
# Semantic versioning components
MAJOR = 1
MINOR = 0
PATCH = 0
# Build metadata
BUILD_DATE = "2025-01-20"
AUTHOR = "Sumit Chatterjee"
DESCRIPTION = "Professional HDR processing nodes using the Debevec Algorithm"
# ComfyUI compatibility
COMFYUI_MIN_VERSION = "0.1.0"
PYTHON_MIN_VERSION = "3.8"
def get_version_string():
"""Get formatted version string"""
return f"v{__version__}"
def get_full_version_info():
"""Get complete version information"""
return {
"version": __version__,
"version_info": __version_info__,
"build_date": BUILD_DATE,
"author": AUTHOR,
"description": DESCRIPTION,
"comfyui_min_version": COMFYUI_MIN_VERSION,
"python_min_version": PYTHON_MIN_VERSION
}