From 2fc7ea1d5f96b0db49ab0dba041ae0e644bc58a7 Mon Sep 17 00:00:00 2001 From: Pablo Apiolazza <31888952+APZmedia@users.noreply.github.com> Date: Mon, 20 Oct 2025 14:32:04 +0200 Subject: [PATCH] Improve light estimation method --- .../TEST-Enhanced-Light-Estimation-v3.json | 1392 ----------------- utils/light_estimator.py | 29 +- 2 files changed, 25 insertions(+), 1396 deletions(-) delete mode 100644 example/TEST-Enhanced-Light-Estimation-v3.json diff --git a/example/TEST-Enhanced-Light-Estimation-v3.json b/example/TEST-Enhanced-Light-Estimation-v3.json deleted file mode 100644 index 8ce96cc..0000000 --- a/example/TEST-Enhanced-Light-Estimation-v3.json +++ /dev/null @@ -1,1392 +0,0 @@ -{ - "id": "enhanced-light-estimation-v3", - "revision": 0, - "last_node_id": 85, - "last_link_id": 250, - "nodes": [ - { - "id": 1, - "type": "LoadImage", - "pos": [-2500, -10000], - "size": [270, 314], - "flags": {}, - "order": 0, - "mode": 0, - "inputs": [], - "outputs": [ - { - "name": "IMAGE", - "type": "IMAGE", - "links": [1, 2, 3] - }, - { - "name": "MASK", - "type": "MASK", - "links": null - } - ], - "properties": { - "cnr_id": "comfy-core", - "ver": "0.3.59", - "Node name for S&R": "LoadImage" - }, - "widgets_values": [ - "Soft-right.png", - "image" - ] - }, - { - "id": 2, - "type": "ImageResizeKJv2", - "pos": [-2200, -10000], - "size": [270, 336], - "flags": {}, - "order": 1, - "mode": 0, - "inputs": [ - { - "name": "image", - "type": "IMAGE", - "link": 1 - }, - { - "name": "mask", - "shape": 7, - "type": "MASK", - "link": null - } - ], - "outputs": [ - { - "name": "IMAGE", - "type": "IMAGE", - "links": [4, 5, 6, 7, 8] - }, - { - "name": "width", - "type": "INT", - "links": null - }, - { - "name": "height", - "type": "INT", - "links": null - }, - { - "name": "mask", - "type": "MASK", - "links": null - } - ], - "properties": { - "cnr_id": "comfyui-kjnodes", - "ver": "1.1.6", - "Node name for S&R": "ImageResizeKJv2" - }, - "widgets_values": [ - 1280, - 1280, - "nearest-exact", - "resize", - "0, 0, 0", - "center", - 2, - "cpu" - ] - }, - { - "id": 3, - "type": "RMBG", - "pos": [-2500, -9500], - "size": [340, 302], - "flags": {}, - "order": 2, - "mode": 0, - "inputs": [ - { - "name": "image", - "type": "IMAGE", - "link": 2 - } - ], - "outputs": [ - { - "name": "IMAGE", - "type": "IMAGE", - "links": null - }, - { - "name": "MASK", - "type": "MASK", - "links": [9, 10] - }, - { - "name": "MASK_IMAGE", - "type": "IMAGE", - "links": null - } - ], - "properties": { - "cnr_id": "comfyui-rmbg", - "ver": "2.9.2", - "Node name for S&R": "RMBG" - }, - "widgets_values": [ - "RMBG-2.0", - 1, - 1024, - 0, - 0, - false, - false, - "Alpha", - "#222222" - ], - "color": "#222e40", - "bgcolor": "#364254" - }, - { - "id": 4, - "type": "LBM_DepthNormal", - "pos": [-1800, -10000], - "size": [271.40234375, 150], - "flags": {}, - "order": 3, - "mode": 0, - "inputs": [ - { - "name": "image", - "type": "IMAGE", - "link": 4 - }, - { - "name": "mask", - "shape": 7, - "type": "MASK", - "link": null - } - ], - "outputs": [ - { - "name": "IMAGE", - "type": "IMAGE", - "links": [11, 12, 13, 14] - } - ], - "properties": { - "cnr_id": "comfyui-lbm", - "ver": "1.1.0", - "Node name for S&R": "LBM_DepthNormal" - }, - "widgets_values": [ - "normal", - 28, - "bf16", - 0.1 - ] - }, - { - "id": 5, - "type": "rgb2x", - "pos": [-1800, -9500], - "size": [270, 130], - "flags": {}, - "order": 4, - "mode": 0, - "inputs": [ - { - "name": "image", - "type": "IMAGE", - "link": 5 - } - ], - "outputs": [ - { - "name": "IMAGE", - "type": "IMAGE", - "links": [15, 16] - } - ], - "properties": { - "cnr_id": "comfyui_rgbx_wrapper", - "ver": "1.0.1", - "Node name for S&R": "rgb2x" - }, - "widgets_values": [ - "irradiance", - 638473917044985, - "randomize", - 56 - ] - }, - { - "id": 6, - "type": "EnhancedLightEstimator", - "pos": [-1000, -10000], - "size": [350, 600], - "flags": {}, - "order": 5, - "mode": 0, - "inputs": [ - { - "name": "normal_map", - "type": "IMAGE", - "link": 11 - }, - { - "name": "luma_image", - "type": "IMAGE", - "link": 6 - }, - { - "name": "exclusion_mask", - "shape": 7, - "type": "MASK", - "link": 9 - } - ], - "outputs": [ - { - "name": "x_direction", - "type": "STRING", - "links": [17] - }, - { - "name": "y_direction", - "type": "STRING", - "links": [18] - }, - { - "name": "combined_direction", - "type": "STRING", - "links": [19] - }, - { - "name": "hard_soft_index", - "type": "STRING", - "links": [20] - }, - { - "name": "x_confidence", - "type": "STRING", - "links": [] - }, - { - "name": "y_confidence", - "type": "STRING", - "links": [] - }, - { - "name": "overall_confidence", - "type": "STRING", - "links": [] - }, - { - "name": "spread_value", - "type": "STRING", - "links": [] - }, - { - "name": "debug_mask", - "type": "IMAGE", - "links": [21] - }, - { - "name": "lit_normals_viz", - "type": "IMAGE", - "links": [22] - }, - { - "name": "cluster_delta_chart", - "type": "IMAGE", - "links": [23] - }, - { - "name": "x_threshold_preview", - "type": "IMAGE", - "links": [24] - }, - { - "name": "y_threshold_preview", - "type": "IMAGE", - "links": [25] - }, - { - "name": "false_color_ire", - "type": "IMAGE", - "links": [26] - }, - { - "name": "shadow_mask", - "type": "IMAGE", - "links": [27] - }, - { - "name": "soft_shadow_mask", - "type": "IMAGE", - "links": [28] - }, - { - "name": "hard_shadow_mask", - "type": "IMAGE", - "links": [29] - }, - { - "name": "ire_legend", - "type": "IMAGE", - "links": [30] - }, - { - "name": "shadow_character", - "type": "STRING", - "links": [31] - }, - { - "name": "transition_quality", - "type": "STRING", - "links": [32] - }, - { - "name": "ire_range", - "type": "STRING", - "links": [33] - }, - { - "name": "shadow_coverage", - "type": "STRING", - "links": [34] - }, - { - "name": "gradient_analysis", - "type": "STRING", - "links": [35] - }, - { - "name": "mean_ire", - "type": "FLOAT", - "links": [] - }, - { - "name": "shadow_percentage", - "type": "FLOAT", - "links": [] - }, - { - "name": "soft_ratio", - "type": "FLOAT", - "links": [] - }, - { - "name": "hard_ratio", - "type": "FLOAT", - "links": [] - }, - { - "name": "mean_gradient", - "type": "FLOAT", - "links": [] - }, - { - "name": "final_shadow_character", - "type": "STRING", - "links": [36] - }, - { - "name": "final_light_quality", - "type": "STRING", - "links": [37] - }, - { - "name": "combined_confidence", - "type": "FLOAT", - "links": [] - }, - { - "name": "analysis_consistency", - "type": "FLOAT", - "links": [] - } - ], - "properties": { - "aux_id": "APZmedia/Comfyui-LightDirection-estimation", - "ver": "enhanced-v3", - "Node name for S&R": "EnhancedLightEstimator" - }, - "widgets_values": [ - 0.5, - "s_curve", - 0.4, - 0.1, - 0.1, - 0.3, - 0.15, - 0.35, - 20.0, - 0.1, - "auto", - "DirectX", - "combined", - 0.5 - ] - }, - { - "id": 7, - "type": "ShowText|pysssss", - "pos": [-500, -10000], - "size": [140, 76], - "flags": {}, - "order": 6, - "mode": 0, - "inputs": [ - { - "name": "text", - "type": "STRING", - "link": 17 - } - ], - "outputs": [ - { - "name": "STRING", - "shape": 6, - "type": "STRING", - "links": null - } - ], - "properties": { - "cnr_id": "comfyui-custom-scripts", - "ver": "f2838e5e59de4d73cde5c98354b87a8d3200190", - "Node name for S&R": "ShowText|pysssss" - }, - "widgets_values": [ - "X Direction" - ] - }, - { - "id": 8, - "type": "ShowText|pysssss", - "pos": [-500, -9900], - "size": [140, 76], - "flags": {}, - "order": 7, - "mode": 0, - "inputs": [ - { - "name": "text", - "type": "STRING", - "link": 18 - } - ], - "outputs": [ - { - "name": "STRING", - "shape": 6, - "type": "STRING", - "links": null - } - ], - "properties": { - "cnr_id": "comfyui-custom-scripts", - "ver": "f2838e5e59de4d73cde5c98354b87a8d3200190", - "Node name for S&R": "ShowText|pysssss" - }, - "widgets_values": [ - "Y Direction" - ] - }, - { - "id": 9, - "type": "ShowText|pysssss", - "pos": [-500, -9800], - "size": [140, 76], - "flags": {}, - "order": 8, - "mode": 0, - "inputs": [ - { - "name": "text", - "type": "STRING", - "link": 19 - } - ], - "outputs": [ - { - "name": "STRING", - "shape": 6, - "type": "STRING", - "links": null - } - ], - "properties": { - "cnr_id": "comfyui-custom-scripts", - "ver": "f2838e5e59de4d73cde5c98354b87a8d3200190", - "Node name for S&R": "ShowText|pysssss" - }, - "widgets_values": [ - "Combined Direction" - ] - }, - { - "id": 10, - "type": "ShowText|pysssss", - "pos": [-500, -9700], - "size": [140, 76], - "flags": {}, - "order": 9, - "mode": 0, - "inputs": [ - { - "name": "text", - "type": "STRING", - "link": 20 - } - ], - "outputs": [ - { - "name": "STRING", - "shape": 6, - "type": "STRING", - "links": null - } - ], - "properties": { - "cnr_id": "comfyui-custom-scripts", - "ver": "f2838e5e59de4d73cde5c98354b87a8d3200190", - "Node name for S&R": "ShowText|pysssss" - }, - "widgets_values": [ - "Hard/Soft Index" - ] - }, - { - "id": 11, - "type": "ShowText|pysssss", - "pos": [-500, -9600], - "size": [140, 76], - "flags": {}, - "order": 10, - "mode": 0, - "inputs": [ - { - "name": "text", - "type": "STRING", - "link": 31 - } - ], - "outputs": [ - { - "name": "STRING", - "shape": 6, - "type": "STRING", - "links": null - } - ], - "properties": { - "cnr_id": "comfyui-custom-scripts", - "ver": "f2838e5e59de4d73cde5c98354b87a8d3200190", - "Node name for S&R": "ShowText|pysssss" - }, - "widgets_values": [ - "Shadow Character" - ] - }, - { - "id": 12, - "type": "ShowText|pysssss", - "pos": [-500, -9500], - "size": [140, 76], - "flags": {}, - "order": 11, - "mode": 0, - "inputs": [ - { - "name": "text", - "type": "STRING", - "link": 32 - } - ], - "outputs": [ - { - "name": "STRING", - "shape": 6, - "type": "STRING", - "links": null - } - ], - "properties": { - "cnr_id": "comfyui-custom-scripts", - "ver": "f2838e5e59de4d73cde5c98354b87a8d3200190", - "Node name for S&R": "ShowText|pysssss" - }, - "widgets_values": [ - "Transition Quality" - ] - }, - { - "id": 13, - "type": "ShowText|pysssss", - "pos": [-500, -9400], - "size": [140, 76], - "flags": {}, - "order": 12, - "mode": 0, - "inputs": [ - { - "name": "text", - "type": "STRING", - "link": 36 - } - ], - "outputs": [ - { - "name": "STRING", - "shape": 6, - "type": "STRING", - "links": null - } - ], - "properties": { - "cnr_id": "comfyui-custom-scripts", - "ver": "f2838e5e59de4d73cde5c98354b87a8d3200190", - "Node name for S&R": "ShowText|pysssss" - }, - "widgets_values": [ - "Final Shadow Character" - ] - }, - { - "id": 14, - "type": "ShowText|pysssss", - "pos": [-500, -9300], - "size": [140, 76], - "flags": {}, - "order": 13, - "mode": 0, - "inputs": [ - { - "name": "text", - "type": "STRING", - "link": 37 - } - ], - "outputs": [ - { - "name": "STRING", - "shape": 6, - "type": "STRING", - "links": null - } - ], - "properties": { - "cnr_id": "comfyui-custom-scripts", - "ver": "f2838e5e59de4d73cde5c98354b87a8d3200190", - "Node name for S&R": "ShowText|pysssss" - }, - "widgets_values": [ - "Final Light Quality" - ] - }, - { - "id": 15, - "type": "PreviewImage", - "pos": [-300, -10000], - "size": [140, 246], - "flags": {}, - "order": 14, - "mode": 0, - "inputs": [ - { - "name": "images", - "type": "IMAGE", - "link": 21 - } - ], - "outputs": [], - "properties": { - "cnr_id": "comfy-core", - "ver": "0.3.59", - "Node name for S&R": "PreviewImage" - }, - "widgets_values": [] - }, - { - "id": 16, - "type": "PreviewImage", - "pos": [-300, -9700], - "size": [140, 246], - "flags": {}, - "order": 15, - "mode": 0, - "inputs": [ - { - "name": "images", - "type": "IMAGE", - "link": 22 - } - ], - "outputs": [], - "properties": { - "cnr_id": "comfy-core", - "ver": "0.3.59", - "Node name for S&R": "PreviewImage" - }, - "widgets_values": [] - }, - { - "id": 17, - "type": "PreviewImage", - "pos": [-300, -9400], - "size": [140, 246], - "flags": {}, - "order": 16, - "mode": 0, - "inputs": [ - { - "name": "images", - "type": "IMAGE", - "link": 23 - } - ], - "outputs": [], - "properties": { - "cnr_id": "comfy-core", - "ver": "0.3.59", - "Node name for S&R": "PreviewImage" - }, - "widgets_values": [] - }, - { - "id": 18, - "type": "PreviewImage", - "pos": [-300, -9100], - "size": [140, 246], - "flags": {}, - "order": 17, - "mode": 0, - "inputs": [ - { - "name": "images", - "type": "IMAGE", - "link": 24 - } - ], - "outputs": [], - "properties": { - "cnr_id": "comfy-core", - "ver": "0.3.59", - "Node name for S&R": "PreviewImage" - }, - "widgets_values": [] - }, - { - "id": 19, - "type": "PreviewImage", - "pos": [-300, -8800], - "size": [140, 246], - "flags": {}, - "order": 18, - "mode": 0, - "inputs": [ - { - "name": "images", - "type": "IMAGE", - "link": 25 - } - ], - "outputs": [], - "properties": { - "cnr_id": "comfy-core", - "ver": "0.3.59", - "Node name for S&R": "PreviewImage" - }, - "widgets_values": [] - }, - { - "id": 20, - "type": "PreviewImage", - "pos": [-300, -8500], - "size": [140, 246], - "flags": {}, - "order": 19, - "mode": 0, - "inputs": [ - { - "name": "images", - "type": "IMAGE", - "link": 26 - } - ], - "outputs": [], - "properties": { - "cnr_id": "comfy-core", - "ver": "0.3.59", - "Node name for S&R": "PreviewImage" - }, - "widgets_values": [] - }, - { - "id": 21, - "type": "PreviewImage", - "pos": [-300, -8200], - "size": [140, 246], - "flags": {}, - "order": 20, - "mode": 0, - "inputs": [ - { - "name": "images", - "type": "IMAGE", - "link": 27 - } - ], - "outputs": [], - "properties": { - "cnr_id": "comfy-core", - "ver": "0.3.59", - "Node name for S&R": "PreviewImage" - }, - "widgets_values": [] - }, - { - "id": 22, - "type": "PreviewImage", - "pos": [-300, -7900], - "size": [140, 246], - "flags": {}, - "order": 21, - "mode": 0, - "inputs": [ - { - "name": "images", - "type": "IMAGE", - "link": 28 - } - ], - "outputs": [], - "properties": { - "cnr_id": "comfy-core", - "ver": "0.3.59", - "Node name for S&R": "PreviewImage" - }, - "widgets_values": [] - }, - { - "id": 23, - "type": "PreviewImage", - "pos": [-300, -7600], - "size": [140, 246], - "flags": {}, - "order": 22, - "mode": 0, - "inputs": [ - { - "name": "images", - "type": "IMAGE", - "link": 29 - } - ], - "outputs": [], - "properties": { - "cnr_id": "comfy-core", - "ver": "0.3.59", - "Node name for S&R": "PreviewImage" - }, - "widgets_values": [] - }, - { - "id": 24, - "type": "PreviewImage", - "pos": [-300, -7300], - "size": [140, 246], - "flags": {}, - "order": 23, - "mode": 0, - "inputs": [ - { - "name": "images", - "type": "IMAGE", - "link": 30 - } - ], - "outputs": [], - "properties": { - "cnr_id": "comfy-core", - "ver": "0.3.59", - "Node name for S&R": "PreviewImage" - }, - "widgets_values": [] - }, - { - "id": 25, - "type": "IREShadowAnalyzer", - "pos": [-1000, -9000], - "size": [350, 400], - "flags": {}, - "order": 24, - "mode": 0, - "inputs": [ - { - "name": "image", - "type": "IMAGE", - "link": 7 - } - ], - "outputs": [ - { - "name": "false_color_ire", - "type": "IMAGE", - "links": [38] - }, - { - "name": "shadow_mask", - "type": "IMAGE", - "links": [39] - }, - { - "name": "soft_shadow_mask", - "type": "IMAGE", - "links": [40] - }, - { - "name": "hard_shadow_mask", - "type": "IMAGE", - "links": [41] - }, - { - "name": "ire_legend", - "type": "IMAGE", - "links": [42] - }, - { - "name": "shadow_character", - "type": "STRING", - "links": [43] - }, - { - "name": "transition_quality", - "type": "STRING", - "links": [44] - }, - { - "name": "ire_range", - "type": "STRING", - "links": [45] - }, - { - "name": "shadow_coverage", - "type": "STRING", - "links": [46] - }, - { - "name": "gradient_analysis", - "type": "STRING", - "links": [47] - }, - { - "name": "mean_ire", - "type": "FLOAT", - "links": [] - }, - { - "name": "shadow_percentage", - "type": "FLOAT", - "links": [] - }, - { - "name": "soft_ratio", - "type": "FLOAT", - "links": [] - }, - { - "name": "hard_ratio", - "type": "FLOAT", - "links": [] - }, - { - "name": "mean_gradient", - "type": "FLOAT", - "links": [] - } - ], - "properties": { - "aux_id": "APZmedia/Comfyui-LightDirection-estimation", - "ver": "enhanced-v3", - "Node name for S&R": "IREShadowAnalyzer" - }, - "widgets_values": [ - 20.0, - 0.1, - "full" - ] - }, - { - "id": 26, - "type": "PreviewImage", - "pos": [-600, -9000], - "size": [140, 246], - "flags": {}, - "order": 25, - "mode": 0, - "inputs": [ - { - "name": "images", - "type": "IMAGE", - "link": 38 - } - ], - "outputs": [], - "properties": { - "cnr_id": "comfy-core", - "ver": "0.3.59", - "Node name for S&R": "PreviewImage" - }, - "widgets_values": [] - }, - { - "id": 27, - "type": "PreviewImage", - "pos": [-600, -8700], - "size": [140, 246], - "flags": {}, - "order": 26, - "mode": 0, - "inputs": [ - { - "name": "images", - "type": "IMAGE", - "link": 39 - } - ], - "outputs": [], - "properties": { - "cnr_id": "comfy-core", - "ver": "0.3.59", - "Node name for S&R": "PreviewImage" - }, - "widgets_values": [] - }, - { - "id": 28, - "type": "PreviewImage", - "pos": [-600, -8400], - "size": [140, 246], - "flags": {}, - "order": 27, - "mode": 0, - "inputs": [ - { - "name": "images", - "type": "IMAGE", - "link": 40 - } - ], - "outputs": [], - "properties": { - "cnr_id": "comfy-core", - "ver": "0.3.59", - "Node name for S&R": "PreviewImage" - }, - "widgets_values": [] - }, - { - "id": 29, - "type": "PreviewImage", - "pos": [-600, -8100], - "size": [140, 246], - "flags": {}, - "order": 28, - "mode": 0, - "inputs": [ - { - "name": "images", - "type": "IMAGE", - "link": 41 - } - ], - "outputs": [], - "properties": { - "cnr_id": "comfy-core", - "ver": "0.3.59", - "Node name for S&R": "PreviewImage" - }, - "widgets_values": [] - }, - { - "id": 30, - "type": "PreviewImage", - "pos": [-600, -7800], - "size": [140, 246], - "flags": {}, - "order": 29, - "mode": 0, - "inputs": [ - { - "name": "images", - "type": "IMAGE", - "link": 42 - } - ], - "outputs": [], - "properties": { - "cnr_id": "comfy-core", - "ver": "0.3.59", - "Node name for S&R": "PreviewImage" - }, - "widgets_values": [] - }, - { - "id": 31, - "type": "ShowText|pysssss", - "pos": [-450, -9000], - "size": [140, 76], - "flags": {}, - "order": 30, - "mode": 0, - "inputs": [ - { - "name": "text", - "type": "STRING", - "link": 43 - } - ], - "outputs": [ - { - "name": "STRING", - "shape": 6, - "type": "STRING", - "links": null - } - ], - "properties": { - "cnr_id": "comfyui-custom-scripts", - "ver": "f2838e5e59de4d73cde5c98354b87a8d3200190", - "Node name for S&R": "ShowText|pysssss" - }, - "widgets_values": [ - "IRE Shadow Character" - ] - }, - { - "id": 32, - "type": "ShowText|pysssss", - "pos": [-450, -8900], - "size": [140, 76], - "flags": {}, - "order": 31, - "mode": 0, - "inputs": [ - { - "name": "text", - "type": "STRING", - "link": 44 - } - ], - "outputs": [ - { - "name": "STRING", - "shape": 6, - "type": "STRING", - "links": null - } - ], - "properties": { - "cnr_id": "comfyui-custom-scripts", - "ver": "f2838e5e59de4d73cde5c98354b87a8d3200190", - "Node name for S&R": "ShowText|pysssss" - }, - "widgets_values": [ - "IRE Transition Quality" - ] - }, - { - "id": 33, - "type": "ShowText|pysssss", - "pos": [-450, -8800], - "size": [140, 76], - "flags": {}, - "order": 32, - "mode": 0, - "inputs": [ - { - "name": "text", - "type": "STRING", - "link": 45 - } - ], - "outputs": [ - { - "name": "STRING", - "shape": 6, - "type": "STRING", - "links": null - } - ], - "properties": { - "cnr_id": "comfyui-custom-scripts", - "ver": "f2838e5e59de4d73cde5c98354b87a8d3200190", - "Node name for S&R": "ShowText|pysssss" - }, - "widgets_values": [ - "IRE Range" - ] - }, - { - "id": 34, - "type": "ShowText|pysssss", - "pos": [-450, -8700], - "size": [140, 76], - "flags": {}, - "order": 33, - "mode": 0, - "inputs": [ - { - "name": "text", - "type": "STRING", - "link": 46 - } - ], - "outputs": [ - { - "name": "STRING", - "shape": 6, - "type": "STRING", - "links": null - } - ], - "properties": { - "cnr_id": "comfyui-custom-scripts", - "ver": "f2838e5e59de4d73cde5c98354b87a8d3200190", - "Node name for S&R": "ShowText|pysssss" - }, - "widgets_values": [ - "Shadow Coverage" - ] - }, - { - "id": 35, - "type": "ShowText|pysssss", - "pos": [-450, -8600], - "size": [140, 76], - "flags": {}, - "order": 34, - "mode": 0, - "inputs": [ - { - "name": "text", - "type": "STRING", - "link": 47 - } - ], - "outputs": [ - { - "name": "STRING", - "shape": 6, - "type": "STRING", - "links": null - } - ], - "properties": { - "cnr_id": "comfyui-custom-scripts", - "ver": "f2838e5e59de4d73cde5c98354b87a8d3200190", - "Node name for S&R": "ShowText|pysssss" - }, - "widgets_values": [ - "Gradient Analysis" - ] - } - ], - "links": [ - [1, 1, 0, 2, 0, "IMAGE"], - [2, 1, 0, 3, 0, "IMAGE"], - [3, 1, 0, 2, 0, "IMAGE"], - [4, 2, 0, 4, 0, "IMAGE"], - [5, 2, 0, 5, 0, "IMAGE"], - [6, 2, 0, 6, 1, "IMAGE"], - [7, 2, 0, 25, 0, "IMAGE"], - [8, 2, 0, 2, 0, "IMAGE"], - [9, 3, 1, 6, 2, "MASK"], - [10, 3, 1, 6, 2, "MASK"], - [11, 4, 0, 6, 0, "IMAGE"], - [12, 4, 0, 6, 0, "IMAGE"], - [13, 4, 0, 6, 0, "IMAGE"], - [14, 4, 0, 6, 0, "IMAGE"], - [15, 5, 0, 6, 1, "IMAGE"], - [16, 5, 0, 6, 1, "IMAGE"], - [17, 6, 0, 7, 0, "STRING"], - [18, 6, 1, 8, 0, "STRING"], - [19, 6, 2, 9, 0, "STRING"], - [20, 6, 3, 10, 0, "STRING"], - [21, 6, 8, 15, 0, "IMAGE"], - [22, 6, 9, 16, 0, "IMAGE"], - [23, 6, 10, 17, 0, "IMAGE"], - [24, 6, 11, 18, 0, "IMAGE"], - [25, 6, 12, 19, 0, "IMAGE"], - [26, 6, 13, 20, 0, "IMAGE"], - [27, 6, 14, 21, 0, "IMAGE"], - [28, 6, 15, 22, 0, "IMAGE"], - [29, 6, 16, 23, 0, "IMAGE"], - [30, 6, 17, 24, 0, "IMAGE"], - [31, 6, 18, 11, 0, "STRING"], - [32, 6, 19, 12, 0, "STRING"], - [33, 6, 20, 11, 0, "STRING"], - [34, 6, 21, 12, 0, "STRING"], - [35, 6, 22, 12, 0, "STRING"], - [36, 6, 28, 13, 0, "STRING"], - [37, 6, 29, 14, 0, "STRING"], - [38, 25, 0, 26, 0, "IMAGE"], - [39, 25, 1, 27, 0, "IMAGE"], - [40, 25, 2, 28, 0, "IMAGE"], - [41, 25, 3, 29, 0, "IMAGE"], - [42, 25, 4, 30, 0, "IMAGE"], - [43, 25, 5, 31, 0, "STRING"], - [44, 25, 6, 32, 0, "STRING"], - [45, 25, 7, 33, 0, "STRING"], - [46, 25, 8, 34, 0, "STRING"], - [47, 25, 9, 35, 0, "STRING"] - ], - "groups": [ - { - "title": "Enhanced Light Estimation with IRE Shadow Analysis", - "bounding": [-2600, -10200, 1200, 4000], - "color": "#3f789e", - "font_size": 24, - "locked": false - }, - { - "title": "Input Processing", - "bounding": [-2600, -10200, 800, 600], - "color": "#8f4a2b", - "font_size": 18, - "locked": false - }, - { - "title": "Enhanced Light Estimator (Combined Analysis)", - "bounding": [-1100, -10200, 500, 700], - "color": "#2b8f4a", - "font_size": 18, - "locked": false - }, - { - "title": "IRE Shadow Analysis (Standalone)", - "bounding": [-1100, -9200, 500, 500], - "color": "#4a2b8f", - "font_size": 18, - "locked": false - }, - { - "title": "Results & Visualizations", - "bounding": [-400, -10200, 200, 4000], - "color": "#8f2b4a", - "font_size": 18, - "locked": false - } - ], - "config": {}, - "extra": { - "ds": { - "scale": 0.8, - "offset": [2000, 10000] - }, - "frontendVersion": "1.26.13" - }, - "version": 0.4 -} diff --git a/utils/light_estimator.py b/utils/light_estimator.py index 3120785..c204d6a 100644 --- a/utils/light_estimator.py +++ b/utils/light_estimator.py @@ -9,7 +9,7 @@ logger = logging.getLogger(__name__) class CategoricalLightEstimator: def __init__(self, x_threshold=0.4, y_threshold_upper=0.1, y_threshold_lower=0.1, central_threshold=0.3, hard_light_threshold=0.15, soft_light_threshold=0.35, - format_mode="auto", normal_standard="OpenGL"): + format_mode="auto", normal_standard="OpenGL", ev_reference=0.18): # Initialize thresholds self.x_threshold = x_threshold self.y_threshold_upper = y_threshold_upper @@ -20,6 +20,7 @@ class CategoricalLightEstimator: self.format_mode = format_mode self.normal_standard = normal_standard self.detected_format = None + self.ev_reference = ev_reference # Reference for 18% gray in linear space # Initialize Sobel filters for gradient analysis self.sobel_x = torch.tensor([[[1, 0, -1], [2, 0, -2], [1, 0, -1]]], dtype=torch.float32) @@ -74,19 +75,39 @@ class CategoricalLightEstimator: return final_results + def _srgb_to_linear(self, srgb: torch.Tensor) -> torch.Tensor: + """Convert sRGB values to linear light (scene-referred approximation) + Warning: True scene-referred values require RAW input data""" + return torch.where( + srgb <= 0.04045, + srgb / 12.92, + ((srgb + 0.055) / 1.055) ** 2.4 + ) + def _regression_analysis(self, normals, mask, luma_before, luma_after): + # Calculate both display-referred (IRE) and scene-referred (EV) deltas + linear_before = self._srgb_to_linear(luma_before) + linear_after = self._srgb_to_linear(luma_after) + delta_ev = torch.log2(linear_after / (linear_before + 1e-8)) delta_y = luma_after - luma_before + X = torch.stack([normals[...,0], normals[...,1], torch.ones_like(normals[...,0])], dim=-1) - coeffs = torch.linalg.lstsq(X, delta_y.unsqueeze(-1)).solution.squeeze() + coeffs_ev = torch.linalg.lstsq(X, delta_ev.unsqueeze(-1)).solution.squeeze() + coeffs_ire = torch.linalg.lstsq(X, delta_y.unsqueeze(-1)).solution.squeeze() grad_x = F.conv2d(delta_y.unsqueeze(1), self.sobel_x.unsqueeze(1)) grad_y = F.conv2d(delta_y.unsqueeze(1), self.sobel_y.unsqueeze(1)) grad_mag = torch.sqrt(grad_x**2 + grad_y**2) return { - 'regression_vector': coeffs[:2].tolist(), + 'ev_coefficients': coeffs_ev[:2].tolist(), + 'ire_coefficients': coeffs_ire[:2].tolist(), 'gradient_softness': self._calc_gradient_softness(grad_mag, delta_y), - 'regression_coefficients': coeffs.tolist() + 'regression_coefficients': coeffs_ire.tolist(), # Backwards compatibility + 'delta_ev': delta_ev, + 'delta_y': delta_y, + 'ev_reference': self.ev_reference, + 'ev_warning': 'EV values approximate - calculated from sRGB inputs' } def _calc_gradient_softness(self, grad_mag, delta_y):