Evercoder / culori

A comprehensive color library for JavaScript.
https://culorijs.org
MIT License
817 stars 30 forks source link

Add DIN99c/d color space #229

Open rumpelrausch opened 4 months ago

rumpelrausch commented 4 months ago

DIN99c and DIN99d are the latest iterations over the "official" DIN99b color space. It promises best accuracy for simple euclidian color distance calculation.

Goals:

Unfortunatly you can't just convert CIELab to DIN99c/d because it needs a different CIELab calculation first: For better accuracy in the blue regions they modify X from XYZ. The chain would be: Anything -> XYZ -> modify X to X' -> CIELab' -> DIN99c/d.

The best formula source I could find so far is in German language, alas: https://tuprints.ulb.tu-darmstadt.de/5870/13/D17%20Einfluss%20der%20Normspektralwertfunktionen%20_final_digital.pdf, pages 29ff. I could help translating it, if needed.

danburzo commented 4 months ago

Hi @rumpelrausch, the latest version of the DIN 6176 standard from 2018 is called Colorimetric determination of colour differences of object colours according to the DIN99o formula.

I was under the impression that DIN99o (the version we implement under the dlab color space) is the latest iteration of the formula. The paper you linked to is from 2015, so it may refer to an older status quo?

rumpelrausch commented 4 months ago

That german PDF shows formula for all DIN99 variants, but does not mention the formula for DIN99o / DIN 6176. I have no access to the DIN99o formula description; It might just implement DIN99b. Looking at the culori source code for convertLab65ToDlch it seems to implement DIN99b.

Coming from the wikipedia description and those from the german PDF the DIN99c/d are the formula we're looking for, regardless whether DIN99o actually contains them. The major trick is the the calculation of a different Lab with modified X value. That's not what culori does.

The easiest way to find out whether it's the "blue adapted" versions is looking at the "L" or "f" calculation. Culori definitely does DIN99b and features no "intermediate adapted Lab".

Still trying to get my hands on the DIN PDF, though...


Ah, according to https://de.wikipedia.org/wiki/DIN99-Farbraum DIN99o implements the DIN99b formula.

rumpelrausch commented 4 months ago

Here's another doc that might shed some light: https://repository.rit.edu/cgi/viewcontent.cgi?article=5577&context=theses Chapter 2.4.5 explains:

DIN99o is the latest modification on DIN99 color space [Witt, 2009]. DIN99o has a similar form as DIN99b, but a parametric factor was added to the lightness channel for future use in compensating for differences between different datasets.

These factors, kE and kCH, are fixed to 1 in culori, so it's identical to DIN99b.

A series of modifications were made on the DIN99 color space in 2002 and named as DIN99b, DIN99c and DIN99d [Cui, 2002]. Among them, DIN99d has the best performance and is shown in Equations (2.40) – (2.49). In the DIN99d formula, tristimulus values X was modified by subtracting a portion of Z to improve the performance in the blue area [Kuehni, 1999]. A different degree of rotation to DIN99 was applied in the new color space DIN99d.

So, DIN99o lacks the bluish adaptions from DIN99d. Sadly DIN99c/d never got much public attention, even though in most of the papers it's said to provide the best performance, closest to CIEDE2000. A chance to be ahead of things... ;-)

I forked culori and started experimenting with two additional color spaces, d99c and d99d. It works but leaves some questions and todos. If it's OK I'll create a draft pull request.

danburzo commented 4 months ago

Thank you for the pointers!

For a web library such as Culori, the main reticence to adding color spaces is the increase in bundle size. Although in our case the tree-shakeable entry point can alleviate the issue, most people will use the default entry point, so it’s worth weighing how exotic a color space is vs. the cost it incurs to figure out if it belongs in the core library.

It appears it’s mostly DIN99d that gets mentioned in several papers:

…so I suggest for now we limit ourselves to the Cartesian and polar versions of this color space and defer for now the DIN99c-based ones.

When I added DIN99o, I used dlab and dlch without regards to the other, related formulas, so they’re now a bit tricky to fit in… I suggest the identifiers din99dlab and din99dlch. (And, in a future major version bump, maybe we deprecate dlab in favor of d99olab?)

If you’re okay with the plan, I’ll provide further feedback on the PR you opened.

rumpelrausch commented 3 months ago

About deprecating dlab: People might use it productively in their projects, and npm et al aren't very supportive about feature migration. IMHO it should at least be maintained as a masquerade so that any unit tests against it stayed green.

The math to get from XYZ to din99c/d is not too hard, it just wasn't easy to find any proper documentation. However, I'm unable to create the reverse math, so (from the culori point of view) any implementation would stay incomplete unless someone else came up with the correct formula.

If it was OK for you I'd just leave this draft PR as it is. If anyone needed din99c/d output they may use it as a base.

danburzo commented 2 months ago

Sorry for the late response. I’ll try to provide the reverse transforms.