Differences
This shows you the differences between two versions of the page.
Next revision | Previous revisionNext revisionBoth sides next revision | ||
isp:brightness [2019/05/08 16:37] – created Igor Yefmov | isp:brightness [2023/09/10 20:56] – [Algorithm] Igor Yefmov | ||
---|---|---|---|
Line 1: | Line 1: | ||
====== Brightness ====== | ====== Brightness ====== | ||
- | In the simplest terms the " | + | In the simplest terms the " |
Again, in the simplest terms, increasing or reducing pixel' | Again, in the simplest terms, increasing or reducing pixel' | ||
- | With that the implementation of the Brightness adjustment can be as simple as the following (where the " | + | ===== In RGB color space ===== |
+ | The mathematically correct way to do the brightness is to first convert into HSL color space, adjust the L (luma) component, and then convert back into RGB. That gives the correct result but costs way too many transistors and cycles. So we've got to improvise! | ||
+ | |||
+ | ==== Algorithm ==== | ||
+ | Here's the algorithm to follow, assuming \(R, G, B \in [0..4095]\) and \(br \in [-1024..+1023]\): | ||
+ | - calculate luminosity | ||
+ | - adjust the brightness additively and clamp the value to range \([0..4095]\) | ||
+ | - figure out the slope for each components based on whether luma is below or above 50% and set chroma components to values that correspond to that 50% luma | ||
+ | - figure out if the new luma is going to cross the 50% boundary and if so - "flip the slopes" | ||
+ | - recalculate RGB components | ||
+ | |||
+ | ==== Calculation reference ==== | ||
+ | |||
+ | To calculate luminosity we just find the max and min of the triplet and get a simple average: | ||
+ | \[L = \frac{min(R, | ||
+ | |||
+ | The slope \(k_R\) for the red component calculation depends on whether \(L\) is above or below the middle: | ||
+ | \[ | ||
+ | k_{R} = | ||
+ | \begin{cases} | ||
+ | R / L & \text{if} \; L \leq 2047 \\ | ||
+ | \frac{R - 2047}{L - 2047} & \text{if} \; L > 2047 | ||
+ | \end{cases} | ||
+ | \] | ||
+ | |||
+ | Brightness adjustment is a trivial addition, clamping the value to its proper limits: | ||
+ | |||
+ | \[ | ||
+ | L` = L + br \\ | ||
+ | L` \in [0..4095] | ||
+ | \] | ||
+ | |||
+ | Applying the new \(L`\) to R component and clamping the result is trivial: | ||
+ | |||
+ | \[ | ||
+ | R` = k_R * (L` - 2047) + R \\ | ||
+ | R` \in [0..4095] | ||
+ | \] | ||
+ | |||
+ | \(G\) and \(B\) calculations are similar to \(R\). | ||
+ | |||
+ | ===== In HSL color space ===== | ||
+ | When using the HSL color space the adjustment is as simple as elementary school' | ||
+ | |||
+ | With that the implementation of the Brightness adjustment can be as simple as the following (where the " | ||
<code c++>// pseudo-code | <code c++>// pseudo-code | ||
void brightness(/ | void brightness(/ |