Ogeon / palette

A Rust library for linear color calculations and conversion
Apache License 2.0
749 stars 60 forks source link

Implement LMS color space and CVD simulation #352

Closed Flourish38 closed 2 months ago

Flourish38 commented 1 year ago

I was considering making my own crate for this, but figured it would probably make sense in the main palette crate. Just wanted to ask before I started work on it.

I have a project that needs color vision deficiency (CVD) simulation, and I think it would be a good fit for Palette. Along the way, this would involve implementing the LMS color space, which I think would also be a good fit for Palette, since CVD simulation is not its only practical use (could even relate to #64? Spectrum to LMS makes arguably more sense).

The method of simulating CVD that I am planning on implementing is Brettel & Mollon 1997, as per the Review of Open Source Color Blindness Simulations by DaltonLens, which I highly recommend reading as it seems to be the only comprehensive overview of the topic. I would like input if someone thinks that another CVD simulation method would be a better fit, or if implementing multiple methods would be better, which I would also be happy to do.

Thank you for the input!

Ogeon commented 1 year ago

Hi, this sounds like an interesting project! I'll have to read up on this later, when I'm less tired (it's getting late over here). Regardless, I think it make sense to add some form of LMS, probably parameterized on which matrix it uses. :slightly_smiling_face:

As for CVD simulation, that sounds like it fits better as a separate crate, if I understand it correctly. Palette can definitely be the building blocks, with LMS being the missing step, but the simulation looks like it may be a whole field of its own. Correct me if I'm wrong. :thinking:

could even relate to #64? Spectrum to LMS makes arguably more sense

XYZ from a spectrum is quite straight forward, but that doesn't prevent supporting LMS too. :grin:

Flourish38 commented 11 months ago

Yeah, I could see why you might want it in a separate crate. I still think it would be good to have it as part of palette, for a similar reason that the color difference metrics are in palette: They are a very common use case for certain color spaces. I don't have a super strong opinion one way or the other though.

Flourish38 commented 11 months ago

I'm looking to start implementing LMS now, is there a color that I should use for reference as to how to implement it?

Ogeon commented 11 months ago

Let's start with the LMS and give the rest some thought. I need to understand how much work it would be to maintain it and keep it up to date with the development in the area. I don't have the personal bandwidth to keep up with the research on my own, even though it's interesting, so I have to prioritize a bit. The best scenario is if we can find some parts that are generic, established/standardized or very commonly used.

For LMS, I think you can look at XYZ. It's a plain tri-stimulus space without a lot of extra (as opposed to RGB). But you can also take a look at how the RGB standards work, it may help. I'm also trying to write some sort of guide or check list for how to add a new color type, but don't wait for that before starting. You probably know this better than I do, but my impression is that it would make sense to have a representation of the conversion matrix as the meta variable (XYZ has the reference white point for convenience). Or are they interchangeable once converted?

Ogeon commented 6 months ago

To respond to https://github.com/Ogeon/palette/issues/376#issuecomment-1949936566

As far as I understand, the problem with converting from LMS to CIE 1931 XYZ is that the cone response functions (or derived colour matching functions) differ. So, you would actually need to know the precise spectral make-up of the colour in question.

As I said, I'm not an expert in the area, so please correct me if I'm missing something, but my understanding so far is that there are a couple of different ways of using LMS:

  1. Converting via a specific matrix, such as Bradford, and while these may not be entirely accurate, they still have their time and place. It would be easy to have a meta type parameter for which matrix was used, and it would likely be something of a generalization of the already existing chromatic adaptation code.
  2. Converting via spectral representations of colors, which would be more accurate. This requires knowledge about the medium and will most likely require a bunch of runtime info. That means that it's not practical to use a type parameter, beyond perhaps locking a value to a specific model of a medium. A bit like how some arena crates bind keys to arenas. It shouldn't be restricted beyond what's practical, though, and something like how Xyz<Any, T> frees XYZ values from having a reference white is also an option.

I don't consider these two cases as mutually exclusive, but case 1 is much more well defined and supported at the moment. I think case 2 could also work within the same system, but it's not something I have tried yet.

marcpabst commented 6 months ago

Thanks for looking into this! I've been doing some research, and I'm slighlty confused by what the Wikipedia article on LMS colour spaces states:

The transformation for a particular color between LMS and the CIE 1931 XYZ space is not unique. It rather depends highly on the particular form of the spectral distribution J(λ) producing the given color. There is no fixed 3x3 matrix which will transform between the CIE 1931 XYZ coordinates and the LMS coordinates, even for a particular color, much less the entire gamut of colors. Any such transformation will be an approximation at best, generally requiring certain assumptions about the spectral distributions producing the color.

https://en.wikipedia.org/wiki/LMS_color_space

... and what Stockman & Sharpe (2000) write:

CMFs can be linearly transformed to other sets of real and imaginary primary lights, such as the X, Y and Z primaries favored by the CIE, or the L, M and S cone fundamental primaries that underlie all trichromatic color matches. Each transformation is accomplished by multiplying the CMFs by a 3×3 matrix.

Stockman, A. & Sharpe, L. T. The spectral sensitivities of the middle- and long-wavelength-sensitive cones derived from measurements in observers of known genotype. Vision Research 40, 1711–1737 (2000).

I will have to give the Stockman & Sharpe paper a more thorough read, but I feel this is a generally doable.

Ogeon commented 6 months ago

It's also a matter of practicality, at some level. If there is a specific use case for using matrices, no matter if they are perfect or not, then there's value in supporting them. I think that's at least a good starting point for this feature.

Ogeon commented 3 months ago

I have done most of the job of implementing LMS in #400. I will limit this issue to that part and open a separate one for CVD simulation.