Open GoogleCodeExporter opened 9 years ago
Try sqrt(pow(r1-r2,2)+pow(g1-g2,2)+x*pow(b1-b2,2)) where x is a value slightly
less than one to compensate for the human eyes ability to perceive shades of
yellow better than shades of blue.
Original comment by magnu...@algonet.se
on 13 Jul 2013 at 2:37
CIE94 is the best formula I know of (from empirical comparison) :
http://en.wikipedia.org/wiki/Color_difference#CIE94
There is an existing C++ (well, nominally C++; it's pretty much just C, the way
it's written.) implementation in gpick (under BSD license):
http://code.google.com/p/gpick . It's found in
source/color_names/ColorNames.cpp,
with auxiliary functions (eg. RGB->LCH conversion) in source/Color.cpp
Dawnbringer's toolkit also includes a few different color difference algos
designed with an intent of increased perceptual accuracy, working with
RGB/HSV/HSL/HLS colors.
Original comment by fintic...@gmail.com
on 22 Jul 2013 at 4:26
I hadn't updated this issue, but since r1837 (Oct 2011) the formula is the one
by Dawnbringer. Basically, it merges color pairs that have the minimal
26*(r1-r2)² + 55*(g1-g2)² + 19*(b1-b2)²
I have no idea if CIE94 would be better, but I expect it would be very close,
difficult to judge between the two.
IMO, a better axis of improvement would be to change how the two selected
colors are merged : At the moment it does a weighted average in RGB space, and
this is known to not preserve lightness and generally reduce saturation.
Original comment by yrizoud
on 22 Jul 2013 at 9:02
Unless those rgb values are already correctly linearized, CIE94 should be
noticably better quality. For basically the same reasons described in the
following paragraph:
Do you mean linear RGB, or sRGB, when talking about the weighted merge? Just
converting to linear RGB before merging (and converting back to sRGB
afterwards) should dramatically reduce both those problems, as they are typical
of interpolation that is not gamma-correct. gpick's source/Color.cpp includes
a (float-based) implementation of both conversions (as part of RGB<->XYZ
conversion).
Essentially, given input channels in range [0,1], to linearize do:
if (C>0.04045){
C=pow(((C+0.055)/1.055),2.4);
}else{
C=C/12.92;
}
for each channel. (output is also in [0..1] range)
The reverse transform is:
if (C>0.0031308){
C=1.055*(pow(C,1/2.4f))-0.055;
}else{
C=12.92*C;
}
for each channel.
(In case you're not aware why and how gamma-incorrect interpolation is
generally harmful, http://www.4p8.com/eric.brasseur/gamma.html covers it quite
well)
Original comment by fintic...@gmail.com
on 22 Jul 2013 at 12:50
Plain average for merging should be perfectly ok for normal use. Since it's
always the closest colors that are fused, most "corrections" would be minimal
and indistinguishable from the ordinary outcome. Think I've done a few tests
with different procedures/corrections for my scripts that fuses colors...but
never found it made a differance worth the effort. But I'm willing to be proven
wrong ;)
Original comment by annas...@hotmail.com
on 24 Jul 2013 at 5:58
Ok, did some more testing with corrections, including gamma2.2 and there just
isn't much noticable differance (as far as I could see). While there surely can
be desireable to correct fusing of colors with a great colorspace
separation...there's little need for it when mixing closer colors. And more
importantly; Color reduction is a vastly destructive operation that greatly
changes the premise. What reductions to an image that look better or worse is
so subjective that any minute "corrections" of some colors are completely
overshadowed.
(Still, that page was great and I discovered that my brush-scaling script could
be further improved by separate RGB-channel corrections and not just brightness
:))
Original comment by annas...@hotmail.com
on 9 Aug 2013 at 8:20
Original issue reported on code.google.com by
yrizoud
on 12 Sep 2010 at 11:07