gtaylor / python-colormath

A python module that abstracts common color math operations. For example, converting from CIE L*a*b to XYZ, or from RGB to CMYK
python-colormath.readthedocs.org
BSD 3-Clause "New" or "Revised" License
456 stars 82 forks source link

Possible wrong calculation #81

Closed VinceKumar closed 6 years ago

VinceKumar commented 6 years ago

The delta_e_cie2000 function is giving me the wrong calculation of numbers. I was just checking with a calculator online to verify reproducibility. It might be that the online calculator is wrong, but it seems these colors are more similar than opposites.

pt = [7,6,4]
rgb = [35,35,35]

color1_rgb = sRGBColor(*pt)
color2_rgb = sRGBColor(*rgb)
color1_lab = convert_color(color1_rgb,LabColor)
color2_lab = convert_color(color2_rgb, LabColor)
delta_e = delta_e_cie2000(color1_lab, color2_lab)
delta_e

delta_e in this case is 87.9 online calculator says delta_e is 7.4

Happens in both 2.1.1 and 2.2

blue-j commented 6 years ago

RGB values have to go through XYZ before converting to Lab - not sure if colormath performs that for you or not? (I am new to the library and just assessing it and haven't even installed it yet!). Checking against a number of calculators, including Bruce Lindbloom's and EasyRGB, I get a delta E of 7.43 for your values. If you could try converting to XYZ first and then Lab and then calculating delta E 2000 that would be a great check. Also, by default the target illuminant will follow through (D65 in the case of sRGB) and maybe we should convert to D50 when going to XYZ first?

KelSolaar commented 6 years ago

it seems these colors are more similar than opposites.

Well they are actually very different, one is close to black:

image

That being said my own computations yield 7.4342281211262584

KelSolaar commented 6 years ago

@VinceKumar: Out of curiosity have you tried to divide your input colours by 255?

blue-j commented 6 years ago

Delta E 2k is very powerful and accurate model of our visual system and so a dark neutral color vs. nearly black should have a small delta. These are not very different colors perceptually. Around 7.4 looks correct to me for these values (and now we have three independent calculations amounting to 7.4).

KelSolaar commented 6 years ago

Delta E 2k is very powerful and accurate model of our visual system and so a dark neutral color vs. nearly black should have a small delta. These are not very different colors perceptually.

There are better colourspaces to perform colour differences, e.g. CAM02-UCS. In any case the colours are perceptually much different as per my above screenshot. It is quite undeniable :)

FYI, a CIE 2000 Delta E of 7.4 is a very high value, i.e. Much perception of colour difference : [1]

image

References

  1. Yang, Y., Ming, J., & Yu, N. (2012). Color image quality assessment based on CIEDE2000. Advances in Multimedia, 2012. doi:10.1155/2012/273723
blue-j commented 6 years ago

We are splitting hairs here; I agree with you. dE of 7.4 is certainly noticeable.

One question, CIECAM02 is indeed the best, but how does one perform a delta E calculation with values in that space? I'm not aware of any method! Thanks in advance.

KelSolaar commented 6 years ago

We are splitting hairs here;

Well, I'm really just trying to be precise :)

One question, CIECAM02 is indeed the best, but how does one perform a delta E calculation with values in that space?

RGB --> XYZ ---> CIECAM02 (JMh) ---> CAM02-UCS (J'a'b') ---> Delta E Luo et al. (2006)

blue-j commented 6 years ago

Forgive me then for a collaborative parry. Delta E can be considered in two ways - if one is expecting/desiring a match, then your Yang/Ming/Yu table is accurate. But if one is comparing colors more broadly and not expecting a match, then 7.4 actually represents a small difference in the global space of possible differences.

Thank you so much for the Luo citation and pipeline! I'm eager to review this!

blue-j commented 6 years ago

I'll leave a link to the Luo et al. (2006) here for other's benefit in case anyone interested reads this thread: https://s3-us-west-2.amazonaws.com/4843ec7c-89cf-4d26-a36a-0e40ebc9a3a7/luo2006.pdf

blue-j commented 6 years ago

I believe I have figured out the problem @VinceKumar It is quite similar to @KelSolaar 's suggestion. When specifying the RGB values, you have to specify explicitly that they are 0-255 values like this:

sRGBColor(35, 35, 35, is_upscaled=True)

Without "is_upscaled=True" you get the wrong result.

KelSolaar commented 6 years ago

Side note: this parameter should really be something like is_8_bit.

blue-j commented 6 years ago

in case it is helpful:

from colormath.color_conversions import convert_color from colormath.color_objects import LabColor, sRGBColor from colormath.color_diff import delta_e_cie2000

rgb1 = sRGBColor(7, 6, 4, is_upscaled=True) lab1 = convert_color(rgb1, LabColor, target_illuminant='D50') rgb2 = sRGBColor(35, 35, 35, is_upscaled=True) lab2 = convert_color(rgb2, LabColor, target_illuminant='D50')
delta_e = delta_e_cie2000(lab1, lab2)

print (delta_e)

Output is 7.430843882682743

blue-j commented 6 years ago

Output is closer to @KelSolaar's above if no _targetilluminant transform is specified and sRGB's D65 is held throughout:

7.434515642877179

KelSolaar commented 6 years ago

python-colormath output is correct assuming one accounts for colour scaling as per https://github.com/gtaylor/python-colormath/issues/81#issuecomment-348909218