-
Notifications
You must be signed in to change notification settings - Fork 47
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Support arithmetic only for linear color spaces #7
Conversation
I do like the diagram :) I'm pretty sure not understanding color space structure is the reason why very confused articles like this exist: http://www.theatlantic.com/technology/archive/2014/08/the-color-of-every-photo-on-the-internet-blended-together-is-orange/378614/ I think someone did point out that it is possible for addition by intermediate conversion into XYZ to produce a point outside the usual color gamut. Removing the vector space operations on nonlinear spaces seems like the only reasonable thing to do. |
Doing arithmetic in a (mathematically) linear color space (XYZ, LMS) makes physical/technical sense, like additive mixing of light sources etc. The meaning in more or less _perceptually_ uniform color spaces like DIN, CIELAB etc. is different. You can do arithmetic on perceptually uniform color spaces as well, but then the result is only meaningful in a perceptual sense, e.g. finding a perceptually uniform gradient between two arbitrary colors. I have to take a closer look at how out of gamut colors are handled, but as far as I remember, they are just clipped to [0, 1], which makes sensible gamut conversions or compressions impossible. You would need to be able to handle values outside this range to check for gamut problems or perform “proper” handling of out of gamut colors. Think of Photoshop rendering intents. So, even if arithmetic is handled only in linear color spaces, there is still the problem of hvs vs. device dependent gamuts like sRGB and (the nonexistent?) AdobeRGB, for example. I hope I understood the point of this properly. I’ll try to look into it and maybe there is an easy way to overcome this problem. |
Yes, these are good points. When you want to do arithmetic on the components of a color directly, you can of course do it. For example, here in this pull request (which I'm not sure is the right thing to be doing). But something as easy as |
I actually disagree with this. In computer vision, metric space or not, people often measure "distance" between colors in RBG space. Of course it's wrong, but it's often good enough, and save translating to an actual metric space. |
What if there were a possibility to enable “illegal” operations by explicitely enforcing them via a parameter/switch, while keeping to legal operations by default? |
That's the whole reason ColorVectorSpace exists...that way |
Okay, got it. I've been following along, but not closely enough to realize that's what this package was for. Cheers! |
Support arithmetic only for linear color spaces
As @jiahao has pointed out, arithmetic is complicated with Colors; in particular, nonlinear colorspaces should not be treated in a cavalier fashion. In Color.jl, we've had support for arithmetic through a more careful procedure:
a+b -> original_colorspace(XYZ(a) + XYZ(b))
, exploiting the fact thatXYZ
is, in fact, a vector space.The problem with this seemingly-rational approach is that it fails due to gamut-correction. This was discovered while adding a "sanity-check" for the diagonal in the diagram that appears in https://github.com/JuliaGraphics/ColorVectorSpace.jl (@jiahao, I think you'll like that diagram). For example, one identity that should be satisfied in any colorspace is
mean(a,a) == a
, wheremean(a,b)
averagesa
andb
. Let's see how we fare with Color.jl:I think the only reasonable option is to disable arithmetic for any color type except those in a linear color space, and force users to do the conversion manually. OK with you, @jiahao?
I'm also CCing @glenn-sweeney or any other colorimetry experts, to ask whether my modification of
sequential_palette
is as intended. Or should we convert toXYZ
before performing those operations?