From e2002cb4c95c4cfedd3df3273c61fa72c5b693a7 Mon Sep 17 00:00:00 2001 From: sumitchatterjee13 Date: Sun, 21 Sep 2025 01:49:57 +1000 Subject: [PATCH] Multiple architectural upgrades Enhanced Algorithms added ev0 based blending algorithm --- CHANGELOG.md | 8 ++++---- README.md | 16 ++++++++-------- luminance_stack_processor.py | 28 ++++++++++++++-------------- 3 files changed, 26 insertions(+), 26 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 48c6420..ac7dc15 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,21 +8,21 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] ### Added -- **NEW: EV0-Based Blending Algorithm** - Now default! Preserves exact EV0 appearance with enhanced dynamic range +- **NEW: Natural Blend Algorithm** - Now default! Preserves exact EV0 appearance with enhanced dynamic range - **Smart luminance masking** - Seamless highlight and shadow detail recovery ### Changed - **Optimized for 8-bit input workflow** - Removed unnecessary 8-bit conversion since inputs are already 8-bit - **Enhanced 16-bit linear output** - Improved scaling algorithm for better 16-bit range utilization -- **Changed default algorithm** - EV0-Based is now default instead of Mertens for natural results +- **Changed default algorithm** - Natural Blend is now default instead of Mertens for natural results ### Fixed -- **CRITICAL: Fixed contrast issues** - EV0-Based algorithm maintains original image contrast +- **CRITICAL: Fixed contrast issues** - Natural Blend algorithm maintains original image contrast - **CRITICAL: Fixed color inversion issues** - Added proper BGR↔RGB conversion for correct color handling - **Fixed brightness problems** - Improved scaling and algorithm selection - **Added Mertens Exposure Fusion algorithm** - Alternative for Lightroom-style results - **Added Robertson algorithm** - Alternative HDR method for different use cases -- **Enhanced algorithm selection** - Users can choose between EV0-Based (default), Mertens, Debevec, and Robertson +- **Enhanced algorithm selection** - Users can choose between Natural Blend (default), Mertens, Debevec, and Robertson - **CRITICAL: Fixed Debevec algorithm issues** - Added Reinhard tone mapping to fix brightness/color inversion - **Improved Debevec output** - Now produces natural results similar to Mertens - **Enhanced per-algorithm scaling** - Different scaling strategies for different algorithms diff --git a/README.md b/README.md index d625ceb..db3496d 100644 --- a/README.md +++ b/README.md @@ -99,7 +99,7 @@ For extended dynamic range with 5 exposures: ## 🔬 How It Works -The nodes implement **multiple HDR algorithms** with **EV0-Based Blending** as the default (preserves natural appearance): +The nodes implement **multiple HDR algorithms** with **Natural Blend** as the default (preserves natural appearance): 1. **Analyzes Multiple Exposures**: Takes differently exposed 8-bit images of the same scene 2. **Estimates Camera Response Function**: Determines how the camera sensor responds to light @@ -109,7 +109,7 @@ The nodes implement **multiple HDR algorithms** with **EV0-Based Blending** as t ### 🎯 **HDR Algorithm Options:** -#### **EV0-Based Blending (Default - Recommended)** +#### **Natural Blend (Default - Recommended)** - **Perfect for natural look**: Uses EV0 as base appearance, adds dynamic range from other exposures - **Zero contrast change**: Output looks exactly like EV0 with enhanced highlight/shadow detail - **Seamless blending**: Uses luminance masks for smooth transitions @@ -146,14 +146,14 @@ The nodes implement **multiple HDR algorithms** with **EV0-Based Blending** as t - Adjust `exposure_step` parameter if using different increments ### Algorithm Selection Guide: -- **Use EV0-Based (Default)**: When you want to keep the exact look of your EV0 image with enhanced dynamic range +- **Use Natural Blend (Default)**: When you want to keep the exact look of your EV0 image with enhanced dynamic range - **Use Mertens**: For natural HDR look similar to Adobe Lightroom (may add some contrast) - **Use Debevec**: For scientific/research work requiring precise scene radiance values - **Use Robertson**: Alternative to Debevec with different mathematical approach ## ⚙️ Technical Details -- **Algorithms**: EV0-Based Blending (default), Mertens Exposure Fusion, Debevec, Robertson +- **Algorithms**: Natural Blend (default), Mertens Exposure Fusion, Debevec, Robertson - **Input Format**: 8-bit ComfyUI IMAGE tensors (0-1 float range from 8-bit sources) - **Output Format**: 16-bit linear colorspace images for extended dynamic range - **Processing**: OpenCV's `createCalibrateDebevec()` and `createMergeDebevec()` @@ -169,13 +169,13 @@ The nodes implement **multiple HDR algorithms** with **EV0-Based Blending** as t - Restart ComfyUI completely 2. **Color inversion or wrong colors**: - - **EV0-Based algorithm** (default) - uses original EV0 colors, no issues expected + - **Natural Blend algorithm** (default) - uses original EV0 colors, no issues expected - **Mertens algorithm** - produces natural colors, no issues expected - **Debevec algorithm** - now includes automatic Reinhard tone mapping for proper colors - **Robertson algorithm** - also includes tone mapping for natural appearance 3. **Image too bright or too dark**: - - **EV0-Based** (default) - keeps exact brightness of your EV0 image + - **Natural Blend** (default) - keeps exact brightness of your EV0 image - **All other algorithms** produce proper brightness levels automatically - **Mertens** - natural brightness similar to Adobe Lightroom - **Debevec/Robertson** - include automatic Reinhard tone mapping for proper brightness @@ -184,8 +184,8 @@ The nodes implement **multiple HDR algorithms** with **EV0-Based Blending** as t - Ensure input images are properly exposed (not all over/under) - Check that images are aligned (use tripod) - Verify EV differences match your capture method - - **For EV0-Based**: Make sure the EV0 image is your desired base appearance - - Try different algorithms: EV0-Based preserves natural look, Mertens for more artistic results + - **For Natural Blend**: Make sure the EV0 image is your desired base appearance + - Try different algorithms: Natural Blend preserves natural look, Mertens for more artistic results 5. **Memory issues**: - Process smaller images first diff --git a/luminance_stack_processor.py b/luminance_stack_processor.py index 450a60b..f30bfb6 100644 --- a/luminance_stack_processor.py +++ b/luminance_stack_processor.py @@ -49,8 +49,8 @@ def cv2_to_tensor(hdr_image: np.ndarray, output_16bit_linear: bool = True, algor # Scale to 16-bit range while preserving linear characteristics # Different scaling strategies based on algorithm - if algorithm_hint == "ev0_base": - # EV0-based should have similar range to original images, use 85th percentile + if algorithm_hint == "natural_blend": + # Natural Blend should have similar range to original images, use 85th percentile scale_reference = np.percentile(hdr_image, 85.0) target_scale = 0.85 # 85% of 16-bit range elif algorithm_hint == "mertens": @@ -79,7 +79,7 @@ def cv2_to_tensor(hdr_image: np.ndarray, output_16bit_linear: bool = True, algor logger.info(f" Original range: [{hdr_image.min():.6f}, {hdr_image.max():.6f}]") # Choose percentile based on algorithm - if algorithm_hint == "ev0_base": + if algorithm_hint == "natural_blend": percentile_used = 85 elif algorithm_hint == "mertens": percentile_used = 90 @@ -162,9 +162,9 @@ class DebevecHDRProcessor: if hdr_radiance.max() <= 1.0: hdr_radiance = hdr_radiance * 2.0 # Boost for better dynamic range - elif algorithm == "ev0_base": - # EV0-based exposure blending - maintains EV0 appearance with enhanced dynamic range - logger.info("Using EV0-based exposure blending...") + elif algorithm == "natural_blend": + # Natural Blend - maintains EV0 appearance with enhanced dynamic range + logger.info("Using Natural Blend exposure blending...") hdr_radiance = self._blend_ev0_based(processed_images, times) elif algorithm == "robertson": @@ -284,7 +284,7 @@ class DebevecHDRProcessor: Returns: Enhanced image that looks like EV0 but with extended dynamic range """ - logger.info("EV0-based blending: Preserving EV0 appearance with enhanced dynamic range") + logger.info("Natural Blend: Preserving EV0 appearance with enhanced dynamic range") # Find the EV0 image (middle exposure - should be the normal exposure) ev0_idx = len(images) // 2 # Middle image is typically EV0 @@ -330,7 +330,7 @@ class DebevecHDRProcessor: # Convert back to 0-255 range for consistency with other algorithms result_8bit = np.clip(result * 255.0, 0, 255).astype(np.uint8) - logger.info("EV0-based blending completed - appearance preserved with enhanced dynamic range") + logger.info("Natural Blend completed - appearance preserved with enhanced dynamic range") return result_8bit.astype(np.float32) / 255.0 # Return as float32 in 0-1 range @@ -385,8 +385,8 @@ class LuminanceStackProcessor3Stops: "step": 0.1, "display": "number" }), - "hdr_algorithm": (["ev0_base", "mertens", "debevec", "robertson"], { - "default": "ev0_base" + "hdr_algorithm": (["natural_blend", "mertens", "debevec", "robertson"], { + "default": "natural_blend" }), } } @@ -399,7 +399,7 @@ class LuminanceStackProcessor3Stops: def __init__(self): self.processor = DebevecHDRProcessor() - def process_3_stop_hdr(self, ev_plus_2, ev_0, ev_minus_2, exposure_step=2.0, hdr_algorithm="ev0_base"): + def process_3_stop_hdr(self, ev_plus_2, ev_0, ev_minus_2, exposure_step=2.0, hdr_algorithm="natural_blend"): """ Process 3-stop HDR merge @@ -469,8 +469,8 @@ class LuminanceStackProcessor5Stops: "step": 0.1, "display": "number" }), - "hdr_algorithm": (["mertens", "debevec", "robertson"], { - "default": "mertens" + "hdr_algorithm": (["natural_blend", "mertens", "debevec", "robertson"], { + "default": "natural_blend" }), } } @@ -483,7 +483,7 @@ class LuminanceStackProcessor5Stops: 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, hdr_algorithm="ev0_base"): + def process_5_stop_hdr(self, ev_plus_4, ev_plus_2, ev_0, ev_minus_2, ev_minus_4, exposure_step=2.0, hdr_algorithm="natural_blend"): """ Process 5-stop HDR merge