Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Color similarity/distance in RGBA color space

How to compute similarity between two colors in RGBA color space? (where the background color is unknown of course)

I need to remap an RGBA image to a palette of RGBA colors by finding the best palette entry for each pixel in the image*.

In the RGB color space the most similar color can be assumed to be the one with the smallest euclidean distance. However, this approach doesn't work in RGBA, e.g., Euclidean distance from rgba(0,0,0,0) to rgba(0,0,0,50%) is smaller than to rgba(100%,100%,100%,1%), but the latter looks much better.

I'm using premultiplied RGBA color space:

r = r×a g = g×a b = b×a 

and I've tried this formula (edit: See the answer below for better formula):

Δr² + Δg² + Δb² + 3 × Δa² 

but it doesn't look optimal — in images with semitransparent gradients it finds wrong colors that cause discontinuities/sharp edges. Linear proportions between opaque colors and alpha seem fishy.

What's the optimal formula?


*) for simplicity of this question I'm ignoring error diffusion, gamma and psychovisual color spaces.


Slightly related: if you want to find nearest color in this non-Euclidean RGBA space, vp-trees are the best.

like image 787
Kornel Avatar asked Jan 21 '11 01:01

Kornel


People also ask

How do you find the distance between colors?

In order to measure the difference between two colors, the difference is assigned to a distance within the color space. In an equidistant-method color space, the color difference ∆E can be determined from the distance between the color places: ΔE = √ (L*₁-L*₂)² + (a*₁-a*₂)² + (b*₁-b*₂)².

What does distance mean in color?

The measured distance (colour difference) between two colours.

How is RGBA color calculated?

To get the percentage equivalent, simply divide the integer by 255 and then multiply by 100%. Going off the previous example, if the RGBA color value is rgba(255, 242, 0, 0.5) then: Red: (255/255) x 100% = 100% Green: (242/255) x 100% = 94.9%

How does RGBA extend the RGB Colour values?

RGBA Colors RGBA color values are an extension of RGB color values with an alpha channel - which specifies the opacity for a color. An RGBA color value is specified with: rgba(red, green, blue, alpha). The alpha parameter is a number between 0.0 (fully transparent) and 1.0 (fully opaque).


1 Answers

Finally, I've found it! After thorough testing and experimentation my conclusions are:

  • The correct way is to calculate maximum possible difference between the two colors.
    Formulas with any kind of estimated average/typical difference had room for discontinuities.

  • I was unable to find a working formula that calculates the distance without blending RGBA colors with some backgrounds.

  • There is no need to take every possible background color into account. It can be simplified down to blending maximum and minimum separately for each of R/G/B channels:

    1. blend the channel in both colors with channel=0 as the background, measure squared difference
    2. blend the channel in both colors with channel=max as the background, measure squared difference
    3. take higher of the two.

Fortunately blending with "white" and "black" is trivial when you use premultiplied alpha.

The complete formula for premultiplied alpha color space is:

rgb *= a // colors must be premultiplied max((r₁-r₂)², (r₁-r₂ - a₁+a₂)²) + max((g₁-g₂)², (g₁-g₂ - a₁+a₂)²) + max((b₁-b₂)², (b₁-b₂ - a₁+a₂)²) 

C Source including SSE2 implementation.

like image 112
Kornel Avatar answered Oct 03 '22 22:10

Kornel