Skip to content

Commit f19489a

Browse files
committed
tweak the luma logic
1 parent 0c68cbb commit f19489a

File tree

1 file changed

+35
-4
lines changed

1 file changed

+35
-4
lines changed

tone_mapping.cpp

Lines changed: 35 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,16 @@
11
#include "tone_mapping.hpp"
22
#include <cstring>
33
#include <memory>
4+
#include <algorithm>
45

56
// Tone mapping constants
67
constexpr float MIN_LUMA_THRESHOLD = 0.001f; // Threshold to avoid division by near-zero luminance
7-
constexpr float REINHARD_LUMINANCE_SCALE = 1.2f; // Gentle luminance boost before tone mapping
8+
constexpr float REINHARD_LUMINANCE_SCALE = 0.85f; // Moderate compression for HDR content
9+
10+
// Helper function to calculate luminance from RGB using Rec.709 coefficients
11+
static inline float calculate_luminance(float r, float g, float b) {
12+
return 0.2126f * r + 0.7152f * g + 0.0722f * b;
13+
}
814

915
cv::Mat* apply_hdr_to_sdr_tone_mapping(
1016
const cv::Mat* src,
@@ -66,6 +72,31 @@ cv::Mat* apply_hdr_to_sdr_tone_mapping(
6672
src_for_transform = bgr_only.get();
6773
}
6874

75+
// Analyze image brightness to adaptively tune tone mapping scale
76+
// Calculate average luminance across the image
77+
float total_luma = 0.0f;
78+
int pixel_count = src_for_transform->rows * src_for_transform->cols;
79+
80+
for (int y = 0; y < src_for_transform->rows; y++) {
81+
const uint8_t* src_row = src_for_transform->ptr<uint8_t>(y);
82+
for (int x = 0; x < src_for_transform->cols; x++) {
83+
int idx = x * 3;
84+
float b = src_row[idx + 0] / 255.0f;
85+
float g = src_row[idx + 1] / 255.0f;
86+
float r = src_row[idx + 2] / 255.0f;
87+
total_luma += calculate_luminance(r, g, b);
88+
}
89+
}
90+
float avg_brightness = total_luma / pixel_count;
91+
92+
// Adaptive scale factor: brighter images get more compression (lower scale)
93+
// Map brightness [0.0-1.0] to scale [0.85-1.1]
94+
// Very bright images (0.7+) get compression (0.85-0.92)
95+
// Moderate images (0.3-0.7) get balanced treatment (0.92-1.02)
96+
// Dark images (0.0-0.3) get slight boost (1.02-1.1)
97+
float adaptive_scale = 1.1f - (avg_brightness * 0.25f);
98+
adaptive_scale = std::max(0.85f, std::min(1.1f, adaptive_scale));
99+
69100
// Apply Reinhard tone mapping
70101
// Tried to use OpenCV's built in tone mapping, but ran into issues with
71102
// dimming blown out/deep fried images. Using this as a first pass
@@ -85,10 +116,10 @@ cv::Mat* apply_hdr_to_sdr_tone_mapping(
85116
float r = src_row[idx + 2] / 255.0f;
86117

87118
// Calculate luminance using Rec.709 coefficients
88-
float luma = 0.2126f * r + 0.7152f * g + 0.0722f * b;
119+
float luma = calculate_luminance(r, g, b);
89120

90-
// Apply gentle Reinhard tone mapping to luminance only
91-
float luma_scaled = luma * REINHARD_LUMINANCE_SCALE;
121+
// Apply Reinhard tone mapping to luminance only with adaptive scale
122+
float luma_scaled = luma * adaptive_scale;
92123
float luma_mapped = luma_scaled / (1.0f + luma_scaled);
93124

94125
// Scale RGB channels by the luminance ratio to preserve color

0 commit comments

Comments
 (0)