Colour 0.3.11 is available
github.com
github.com
Nothing out there can do true color management in pure python. I just wrote a library to handle basic single-color conversion through arbitrary ICC profiles using the lcms ctypes wrapper around littlecms. That was my first foray into ctypes in Python. He no idea what a PITA it would be.
We are a super color critical shop, with modern digital large format printers of just about every type you can imagine: UV to board or roll. Latex. Fabric dye sub. Aqueous inkjet to photographic paper. You name it, we have it.
Client has a specific color we are trying to match. We print a swatch of that color on a printer using Adobe98 RGB values that come from Photoshop or similar. We then read the LAB value of our swatch. We take the delta between the two readings of each LAB coordinate. We then apply that delta to generate a new LAB value. We take that new LAB value and convert it back to Adobe98, and print another swatch. Rinse and repeat until we are as close as we can get.
Occasionally, we will use LCH instead of LAB, which is useful in that it can maintain the perceptive hue of a color across a range of lightness values. In LAB a color's chroma, as perceived by human vision, can skew as lightness changes.
In all of the above, we log every round in a spreadsheet. Sometimes we are trying to match a color that cannot be achieved in RGB. This is usually deep higher-density blues. For those we need to specify our colors in CMYK because they are out of gamut for Adobe98, but still in gamut of our presses.
My python script is tied into Excel on Mac, using a VBA macro via an AppleScript bridge so they can do these conversions automatically. Just enter the deltas on the LAB coordinates, the starting RGB or CMYK value, and the rest is calculated and filled in.
Colormath works fine for the RGB math, but only because it is using relative colorimetric conversions, with a 2 degree observer. But for CMYK, it is completely wrong. It is not using any standard CMYK profile, but is doing some sort of generic conversion that does 100% GCR, where the CMY grayscale component is completely replaced by the equivalent amount of black.
A proper CMYK conversion requires the use of a ICC profiles that have a specific GCR or UCR curve which specifies how much CMY is used for the grey value at any given percentage of grey. This is necessary because if only black ink is used for the grey component, black ink is not enough to print a pleasing image at lighter grey values. There are several standard CMYK profiles. In the US the two most common are US Web Coated SWOP, and GRACoL.
To do conversions between LAB and one of theses CMYK colorspaces requires the use of an color management engine that utilizes ICC profiles to do the conversion. LittleCMS is one such (open source) engine.
By using lcms, not only can I now do conversions in an CMYK ICC space, but also other RGB spaces that colormath does not support, such as ProPhoto or BetaRBG. In addition, I can specify other rendering intents and white points for the conversion. With LittleCMS you can do anything. Remarkably, it even supports hifi color profiles, meaning CMYK plus additional channels of ink, such as orange, green and violet. It supports up to 12-channel profiles, which is remarkable for a free library. In practice, we don't need those for color matching, because even though we have 7-channel presses (if you count white ink), the conversion, say, from RGB to CMYKOG is done in the press RIP.
Reading this makes my stomach sore.
Remember that RGB is not a colour space. Neither is CMYK. Colour encoding models do not necessarily imply a colour space as outlined by the definition of an RGB colour space via ISO 22028-1.
Even Lab encodings will vary based upon the assumed white point.
What is not expressed in saying "RGB" or "CMYK" are the other critical facets that define what they are referencing. In RGB, what are the colours of the three lights and what is the combined white point? In CMYK, what are the colours of the inks, the paper colour / type, and the illuminant in question? The mixture of the unsaid contexts are what define how colours result to a standard observer.
In the case of Lab, one must take care to assert that the same formulation has taken place before comparing values. For example, it isn't enough to just say "RGB" because of the facets above. What are the colours of primary lights in the source RGB space? The destination you are comparing? What are the white points? What is the white point assumed in the formulation for the Lab conversion?
Only when all of the contexts are identical do the values take on meaning, and a valid comparison within the limits of the encoding model is possible.
TL;DR:
* Make sure you are aware of the primaries of the RGB spaces being compared with Lab.
* Make sure your white points are aligned on the RGB spaces being compared with Lab.
* Make sure your RGB spaces are aligned to the white point of the Lab formulation in question.
* Make sure you are linearising your RGB spaces correctly before converting to Lab; every RGB space typically has a unique transfer function.
* Be well aware of the limitations of Lab, such as red turns yellow and blue turns purple hue nonlinearity etc.
* Be using an appropriate model for the intensities of light being compared. Lab, for example, is not well suited for anything beyond diffuse white reflectance values.
Colour should be able to handle all of the above points, and deliver great looking plots as well!
You sound like a perfect candidate to dig into Colour. There are a great many extremely knowledgeable people around that project that can help.
Mark Fairchild's Color Appearance Models is probably about the most canonical tome one can recommend, with the caveat above.
To do what you are seeking, you would need an accurate profile of your camera in question, as well as likely a spectrophotometer for the objects in question. It is a pretty tricky field.
I would encourage you to contact the Colour Science Twitter feed to get in on the Slack channel for help and guidance.
See you there!
Hope your road to stable goes well.