- commit
- eaeb3345f772b0d6cd481343546eaf5a3869de0a
- parent
- 3cae11aff1465d7317e82cfcc91118ac41112a7c
- Author
- Tobias Bengfort <tobias.bengfort@posteo.de>
- Date
- 2026-06-28 08:09
contrast: use latex math
Diffstat
| M | _content/posts/2022-09-10-contrast-algorithms/index.md | 60 | ++++++++++++++++++++++++++++++++++++++---------------------- |
1 files changed, 38 insertions, 22 deletions
diff --git a/_content/posts/2022-09-10-contrast-algorithms/index.md b/_content/posts/2022-09-10-contrast-algorithms/index.md
@@ -17,7 +17,7 @@ claims that can be found throughout the internet. 17 17 18 18 Let's start with some fractions. 19 1920 -1 - **simple contrast**: `Ymax / Ymin`-1 20 - **simple contrast**: $\frac{Y_{max}}{Y_{min}}$ 21 21 22 22 The authors do not have anything nice to say about this one: 23 23 @@ -25,31 +25,39 @@ Let's start with some fractions. 25 25 > much higher dynamic range, and the logarithmic response characteristics 26 26 > of the human eye. 27 2728 -1 - **Weber Contrast**: `(Ymax - Ymin) / Ymin`-1 28 - **Weber Contrast**: $\frac{Y_{max} - Y_{min}}{Y_{min}}$ 29 29 30 30 The authors provide a lot of background information on this one, but fail 31 31 to mention one crucial point: This again is simple contrast, just with an 32 32 offset of 1: 33 3334 -1 (Ymax - Ymin) / Ymin35 -1 = Ymax / Ymin - 1-1 34 $$ -1 35 \frac{Y_{max} - Y_{min}}{Y_{min}} -1 36 = \frac{Y_{max}}{Y_{min}} - 1 -1 37 $$ 36 3837 -1 - **Michelson Contrast**: `(Ymax - Ymin) / (Ymax + Ymin)`-1 39 - **Michelson Contrast**: $\frac{Y_{max} - Y_{min}}{Y_{max} + Y_{min}}$ 38 40 39 41 Again they fail to mention a crucial detail: This is a Weber Contrast40 -1 that compares `Ymax` and the average of `Ymax` and41 -1 `Ymin`:-1 42 that compares $Y_{max}$ and the average of $Y_{max}$ and -1 43 $Y_{min}$: 42 4443 -1 (Ymax - Ymin) / (Ymax + Ymin)44 -1 = (2 * Ymax - (Ymax + Ymin)) / (Ymax + Ymin)45 -1 = (Ymax - (Ymax + Ymin) / 2) / ((Ymax + Ymin) / 2)46 -1 = (Ymax - Yavg) / Yavg-1 45 $$ -1 46 \begin{aligned} -1 47 & \frac{Y_{max} - Y_{min}}{Y_{max} + Y_{min}} \\ -1 48 =& \frac{2 \cdot Y_{max} - (Y_{max} + Y_{min})}{Y_{max} + Y_{min}} \\ -1 49 =& \frac{Y_{max} - Y_{avg}}{Y_{avg}} -1 50 \end{aligned} -1 51 $$ 47 52 48 53 It can also easily be calculated from simple contrast: 49 5450 -1 (Ymax / Ymin - 1) / (Ymax / Ymax + 1)-1 55 $$ -1 56 \frac{Y_{max} - Y_{min}}{Y_{max} + Y_{min}} -1 57 = \frac{\frac{Y_{max}}{Y_{min}} - 1}{\frac{Y_{max}}{Y_{max}} + 1} -1 58 $$ 51 5952 -1 - **WCAG 2.1**: `(Ymax + 0.05) / (Ymin + 0.05)`-1 60 - **WCAG 2.1**: $\frac{Y_{max} + 0.05}{Y_{min} + 0.05}$ 53 61 54 62 The authors correctly observe: 55 63 @@ -75,15 +83,17 @@ together with two thresholds, we can call them *equivalent* if they give the 75 83 same results. 76 84 77 85 Mathematically speaking, we want the following to hold true for all color pairs78 -1 `(a, b)` and `(c, d)`:-1 86 $(a, b)$ and $(c, d)$: 79 8780 -1 f(a, b) < f(c, d) => g(a, b) < g(c, d)-1 88 $$ -1 89 f(a, b) < f(c, d) \Rightarrow g(a, b) < g(c, d) -1 90 $$ 81 91 82 92 In other words, two contrast formulas are equivalent if there is a strictly 83 93 monotonic map between them. I call such a map a "scaling". 84 94 85 95 For example, simple contrast and Weber contrast are equivalent according to86 -1 this definition because `scale(x) = x - 1` is strictly monotonic. The same goes-1 96 this definition because $scale(x) = x - 1$ is strictly monotonic. The same goes 87 97 for Michelson contrast. 88 98 89 99 You could also have a stricter definition and require contrast formulas to be @@ -95,8 +105,8 @@ will work with the weaker definition in this post. 95 105 96 106 ## Lightness difference 97 10798 -1 The authors also mention lightness difference `Lmax -99 -1 Lmin` as a way to calculate contrast:-1 108 The authors also mention lightness difference $L_{max} - -1 109 L_{min}$ as a way to calculate contrast: 100 110 101 111 > Instead of being based on luminance, which is not perceptually uniform (and 102 112 > thus, the visual difference corresponding to a given luminance difference is @@ -106,13 +116,19 @@ Lmin` as a way to calculate contrast: 106 116 Using the CIELab model of lightness is one option, but there are others. 107 117 For example, there is the [Weber-Fechner law][2]: 108 118109 -1 L = a * log(Y) + b-1 119 $$ -1 120 L = a \cdot \log(Y) + b -1 121 $$ 110 122 111 123 So what happens if we build a lightness difference based on that definition? 112 124113 -1 (a * log(Ymax) + b) - (a * log(Ymin) + b)114 -1 = a * (log(Ymax) - log(Ymin))115 -1 = a * log(Ymax / Ymin)-1 125 $$ -1 126 \begin{aligned} -1 127 & (a \cdot \log(Y_{max}) + b) - (a \cdot \log(Y_{min}) + b) \\ -1 128 =& a \cdot (\log(Y_{max}) - \log(Y_{min})) \\ -1 129 =& a \cdot \log(\frac{Y_{max}}{Y_{min}}) -1 130 \end{aligned} -1 131 $$ 116 132 117 133 This turns out to be a scaled version of simple contrast. Even if you consider 118 134 Weber-Fechner to be outdated, this is still a perceptual model. So both the