Not all RGB channels contribute equally to perceived brightness. The human eye has far more green-sensitive cone cells than red or blue, meaning that changes in the green channel have a much larger impact on how bright or dark a color appears. Luminance weighting applies correction factors to account for this asymmetry.
The ITU-R BT.709 Coefficients
The standard luminance coefficients for sRGB (from the HDTV specification) are:
Green contributes over 71% of perceived brightness, red about 21%, and blue just 7%. This is why pure blue (#0000FF) appears much darker than pure green (#00FF00) despite both having a single channel at maximum.
Weighted Euclidean Distance
A common improvement over naive Euclidean RGB distance is to weight the channels by their luminance contribution. Compuphase's "redmean" approximation is a popular cheap approach:
function weightedColorDistance(
r1: number, g1: number, b1: number,
r2: number, g2: number, b2: number,
): number {
const rMean = (r1 + r2) / 2
const dR = r1 - r2
const dG = g1 - g2
const dB = b1 - b2
return Math.sqrt(
(2 + rMean / 256) * dR * dR +
4 * dG * dG +
(2 + (255 - rMean) / 256) * dB * dB
)
}Applications
- Accessibility contrast checks (WCAG uses relative luminance to compute contrast ratios)
- Grayscale conversion (desaturation that preserves perceived brightness)
- Improved palette grouping in our color extraction pipeline
