Closed makew0rld closed 3 years ago
D65 XYZ values are derived from D65 xyY values using the standard formula (with Y being set to 1). It seems that the discrepancy comes from whether to use 4- or 5-decimal space rounding for the x and y numbers. A lot of sources use 5 decimal place rounding 1 2. Bruce Lindbloom references ASTM E308 - 01 which I assume also rounds like this.
HSLuv uses 4 decimal place rounding which seems to be encoded in the sRGB standard: https://en.wikipedia.org/wiki/SRGB#The_sRGB_gamut https://en.wikipedia.org/wiki/Rec._709
Even if 5 decimal place rounding is better, it's certaintly not worth making a revision of the color space for this. I added some comments about this to cie.mac
for future reference. If there is every a revision 5 of HSLuv we can consider sneaking higher precision numbers into it.
So you're saying if I used a white reference equal to (0.9505, 1.0000, 1.0888)
, that would be more correct? And the problem with the one I was using was that it had one extra decimal place?
If that's true than I'm confused why using the longer one (0.95045592705167, 1, 1.089057750759878)
would make my code work. Especially since that one isn't even accurate to 4 decimal places, when compared to the other one.
With regards to your code, I can't really comment since I don't know what exactly you're testing.
I'm urging you to think practically though. What are you trying to achieve where this difference is an issue?
Numbers generated by all these algorithms are always approximations. In the case of colors, remember that the general standard is 24-bit color, which means 8 bits per channel, which means the smallest difference that can be encoded is 1 / 256 ~ 0.004
. That means all decimal places after that are noise.
Another thing to keep is mind is that the precision of your output numbers can only be as good as the least precise of your input numbers. (depending on the calculation.. see: https://en.wikipedia.org/wiki/Propagation_of_uncertainty)
So any benefit of increasing the precision of these: https://github.com/hsluv/hsluv/blob/master/math/cie.mac#L26-L27
... might be lost unless you also increase the precision of these: https://github.com/hsluv/hsluv/blob/master/math/cie.mac#L20-L25
If I use a D65 value of (0.95047, 1.00000, 1.08883)
and run the HSLuv test suite with a delta of 1.0/256.0
, none of the tests that measure the conversion to RGB fail. But I get errors for the conversions from RGB. Obviously this does not really matter practically, but it'd be nice to get these to pass as well. So I used the different white point.
Here's all the errors for one color. Keep in mind this library scales the values from 0-1, rather than 0-255 or 0-100.
hsluv_test.go:65: result: [85.885855 *, 0.504866, 0.423764] expected: [85.87432021817236 0.5050715546882035 0.4237638616967416], testing HsluvFromHex with test case #666644
hsluv_test.go:65: result: [85.885855 *, 0.504866, 0.423764] expected: [85.87432021817236 0.5050715546882035 0.4237638616967416], testing HsluvFromRGB with test case #666644
hsluv_test.go:65: result: [85.885855 *, 0.706252, 0.423764] expected: [85.87432021817236 0.7065317593121714 0.4237638616967416], testing HpluvFromHex with test case #666644
hsluv_test.go:65: result: [85.885855 *, 0.706252, 0.423764] expected: [85.87432021817236 0.7065317593121714 0.4237638616967416], testing HpluvFromRGB with test case #666644
hsluv_test.go:65: result: [0.423764, 0.235854, 85.885855 *] expected: [0.4237638616967416 0.23594798873422232 85.87432021817236], testing convRgbLch with test case #666644
I think I'd rather keep the accuracy and those tests, and I don't think using a different white point will really cause any issues.
So you're saying if I used a white reference equal to
(0.9505, 1.0000, 1.0888)
, that would be more correct? And the problem with the one I was using was that it had one extra decimal place?
@makeworld-the-better-one, I think they're talking about the rounding applied to the chromaticity coordinates, not the final XYZ value for the white point. The sRGB standard states that D65 should be considered to have the chromaticity coordinates '0.3127, 0.3290', which approximately expands to an XYZ value of (0.9504559270516717, 1, 1.089057750759878)
.
If that's true than I'm confused why using the longer one
(0.95045592705167, 1, 1.089057750759878)
would make my code work. Especially since that one isn't even accurate to 4 decimal places, when compared to the other one.
Personally, I'm confused why nobody else just defines it as '0.3127, 0.3290' and then compute the more useful parameters at compile time at maximum precision.
The standard D65 XYZ values are
(0.95047, 1.00000, 1.08883)
. This is written in Wikipedia and by Bruce Lindbloom (see here and search forD65
).But HSLuv defines them like so:
https://github.com/hsluv/hsluv/blob/005e50b7cf79eff8c62ccfc09a5707692451758e/math/cie.mac#L40
If I remove the
rat
and run that calculation, the output XYZ values are(0.95045592705167, 1, 1.089057750759878)
. This is quite a bit off from what I believe are the correct values, and it is throwing off my calculations that use the standard D65 as I defined at the beginning. Here's an example of the difference between what using the standard D65 will output, versus the HSLuv D65:The D65 values affect these variables:
https://github.com/hsluv/hsluv/blob/005e50b7cf79eff8c62ccfc09a5707692451758e/math/cie.mac#L48-L49
Which goes on to affect everything else.
I believe this could all be fixed by manually setting the
[ref_X, ref_Y, ref_Z]
variables to(0.95047, 1.00000, 1.08883)
. I know that I am quite inexperienced with color theory though, and so I'd appreciate learning if I'm wrong here.For now I will specify a custom white reference for HSLuv calculations only.