Differences
This shows you the differences between two versions of the page.
Next revision | Previous revisionNext revisionBoth sides next revision | ||
isp:contrast [2019/05/08 16:55] – created Igor Yefmov | isp:contrast [2023/09/06 09:54] – [In RGB color space] Igor Yefmov | ||
---|---|---|---|
Line 4: | Line 4: | ||
Decreasing the contrast brings the shadows up and highlights down to make them closer to one another. | Decreasing the contrast brings the shadows up and highlights down to make them closer to one another. | ||
- | For our purposes we are going to adjust | + | Essentially when the contrast is increased, |
- | Assuming | + | ===== In RGB color space ===== |
+ | As with the [[isp:: | ||
+ | |||
+ | Traditionally the luminance is calculated as (see [[isp: | ||
+ | |||
+ | \[ | ||
+ | lum = 0.2126 * R + 0.7152 * G + 0.0722 * B | ||
+ | \] | ||
+ | |||
+ | |||
+ | |||
+ | With that in mind each component's contrast adjustment is based on its luma's weight \(k\) and the adjustment itself is calculated as | ||
+ | |||
+ | \[ | ||
+ | component = (component' | ||
+ | component' | ||
+ | contrast \in ]0..2.0]%% | ||
+ | \] | ||
+ | |||
+ | which looks like this: | ||
+ | |||
+ | \[ | ||
+ | \begin{bmatrix} | ||
+ | R - 0.5 \\ | ||
+ | G - 0.5 \\ | ||
+ | B - 0.5 | ||
+ | \end{bmatrix} | ||
+ | | ||
+ | \begin{bmatrix} | ||
+ | 0.2126^2 & 0 & 0 \\ | ||
+ | 0 & 0.7152^2 & 0 \\ | ||
+ | 0 & 0 & 0.0722^2 | ||
+ | \end{bmatrix} \times contrast^2 | ||
+ | + | ||
+ | \begin{bmatrix} | ||
+ | 0.5 \\ | ||
+ | 0.5 \\ | ||
+ | 0.5 | ||
+ | \end{bmatrix} \\ | ||
+ | R, G, B \in [0..1.0] \\ | ||
+ | contrast \in [0..2.0] | ||
+ | \] | ||
+ | |||
+ | Of course, much like in [[isp:: | ||
+ | |||
+ | \[ | ||
+ | \frac{ | ||
+ | \left(\begin{bmatrix} | ||
+ | R \\ | ||
+ | G \\ | ||
+ | B | ||
+ | \end{bmatrix} | ||
+ | - | ||
+ | \begin{bmatrix} | ||
+ | 2047 \\ | ||
+ | 2047 \\ | ||
+ | 2047 | ||
+ | \end{bmatrix} \right) | ||
+ | \begin{bmatrix} | ||
+ | 47394 & 0 & 0 \\ | ||
+ | 0 & 536358 & 0 \\ | ||
+ | 0 & 0 & 5466 | ||
+ | \end{bmatrix} \times contrast^2 | ||
+ | }{1024*1024*1024*1024} + | ||
+ | \begin{bmatrix} | ||
+ | 2047 \\ | ||
+ | 2047 \\ | ||
+ | 2047 | ||
+ | \end{bmatrix} \\ | ||
+ | |||
+ | R, G, B \in [0..4095] \\ | ||
+ | contrast \in [0..2048] | ||
+ | |||
+ | \] | ||
+ | |||
+ | Or, rewritten in a per-component form: | ||
+ | |||
+ | \[ | ||
+ | \begin{cases} | ||
+ | ^{R = R' - 2047 * 47394 * contrast^2 + 2047}/ | ||
+ | ^{G = G' - 2047 * 536358 * contrast^2 + 2047}/ | ||
+ | ^{B = B' - 2047 * 5466 * contrast^2 + 2047}/ | ||
+ | \end{cases} | ||
+ | \] | ||
+ | ===== In HSL color space ===== | ||
+ | For our purposes we are going to adjust the pixel' | ||
+ | |||
+ | Assuming the \(L\) component to be in range \([0..100]%%\) the contrast adjustment looks like this: | ||
+ | \[ | ||
+ | luma = (luma - 50) * contrast^2 + 50 \\ | ||
+ | luma \in [0..100] \\ | ||
+ | contrast \in ]0..2.0]%% | ||
+ | \] | ||
<code c++>// pseudo-code | <code c++>// pseudo-code | ||
void contrast(/ | void contrast(/ | ||
- | for(const & pixel: image){ | + | for(auto & pixel: image){ |
- | pixel.luma = std:: | + | pixel.luma = std:: |
} | } | ||
}</ | }</ | ||