How to cope with colours going out of gamut?

Clipped as it happenend in your example I guess.
In your case the blue channel is clipped. Maybe you can try different settings in the input color module like turn on gamut clipping or other RGB profiles?

You just export it as is.

Is that absolute colorimetric intent?

Is there any solution, or is sRGB too limiting?

As far as I know there is no sane way to display colors that are outside of a (convex) gamut, using colors inside of that gamut. What you can do is to compress the range of colors so they are inside of sRGB by reducing the saturation of the image a bit.

However, to me the artifacts in the blue areas of the image don’t look like it’s not just the gamut clipping.

If you haven’t read this yet, it might help in understanding the problem at hand.
http://www.cambridgeincolour.com/tutorials/color-space-conversion.htm

1 Like

Thanks. That was helpful.

I’m assuming you are using the darktable built-in sRGB profile. This is a bog-standard matrix profile. It doesn’t have a perceptual intent table. I suspect that if you export your file using all four “intents”, you’ll produce four identical files.

Cambridge in Colour is a wonderful website and the referenced article is excellent. However, the output profiles that he’s talking about are Look-Up Table printer or CMYK profiles with four intent tables. The sRGB profile is a matrix profile and doesn’t have any intent tables at all. Without intent tables, you will never have perceptual intent or saturation intent as actual choices, instead you’ll get relative colorimetric intent.

Regarding absolute vs relative colorimetric intent, yes, matrix profiles in theory support both of these intents. But in a V4 workflow such as what darktable uses, converting between matrix RGB working spaces uses relative colorimetric intent even if you ask for absolute colorimetric intent. This was a major point of disagreement in the change from V2 to V4 ICC profile specifications.

Figure 4 in this article shows what an actual absolute colorimetric intent conversion in a V2 workflow looks like:

In either case, V2 or V4, and relative or absolute colorimetric, the conversion to sRGB does clip out of gamut colors. There’s no gamut compression even if you choose perceptual intent, because the sRGB matrix profile (and AdobeRGB, ProPhotoRGB and all other standard RGB working space profiles) are all matrix profiles, which means no tables, which means the only available intents are relative and absolute colorimetric.

And in a V4 workflow, unless your image editor provides a special chromatic adaptation slider (I don’t think darktable does this, GIMP doesn’t, Krita does but I’ve never used it), asking for absolute colorimetric intent when converting to an RGB matrix working space profile actually gives you relative colorimetric intent. Asking for perceptual gives you relative colorimetric. And asking for saturation also gives you relative colorimetric.

You might find this article helpful, though I’d recommend reading the Cambridge in Colour article first:

If you read the above article, I’m still trying to figure out what happens when the source profile has all four tables (this is mostly only relevant when converting for example from a printer profile back to an RGB matrix profile working space, or between two printer profiles), and I’ll update the article if I ever get this somewhat unusual (well, I think it’s probably an unusual thing to do) type of conversion figured out.

As far as sRGB being “weak” or having a small color gamut, yes, it really does have a small color gamut compared to colors that can be captured by today’s digital cameras, displayed on today’s wide gamut monitors, and printed using today’s high-end photographic printers. sRGB is particularly weak in blue-greens, greens, and yellow-greens, exactly the colors in the dragonfly image.

This article explores the question of which colors that can be captured by a digital camera are out of gamut with respect to the sRGB color gamut:

This tutorial has diagrams showing the relative size and shape of various ICC profiles your image might encounter along the way from camera to output:

AdobeRGB will probably easily hold all the colors in the dragonfly image (which is a very pretty photograph, I love the dragonfly’s blue, green, and orange-red colors in front of the out-of-focus background greens). But putting an AdobeRGB image on the web is risky - if your viewing audience is composed of photographers, hopefully most of them have calibrated and profiled monitors, and are using a properly color-managed browser. But for most people even today, color management is not well-implemented on their various viewing devices. So for posting images to the web, sRGB is still the safest choice.

Which as @paperdigits notes, leaves reduction of the saturation of the out of gamut colors before export, and/or allowing the out of gamut colors to simply clip, as the only viable solutions. Personally I try to bring colors back into gamut before exporting to sRGB. But for bright colors, if clipping doesn’t produce any visible artifacts then usually I just let the colors clip.

5 Likes

Thank you. That was very helpful.

I conclude:

  1. Changing the intent in the darktable export module won’t help me.
  2. Using a wider gamut such as AdobeRGB won’t help me because:
    a) My monitor does not have that wide a gamut (99% of sRGB is all that it claims - profiling and calibrating seems to back up that claim) and
    b) I am publishing either to the web for general consumption (not specifically photographers) or for my personal printing on a printer that has a gamut smaller than sRGB.
  3. So my options are to live with what I’m getting, or to try to push the colours back into sRGB within my current workflow (darktable). The latter is beyond me at present (I don’t know how to go about it). So I’ll stick with the former for now.

What about this video tutorial by @RileyB:

Not seen it before. I’ll take a look.
Thanks.

[quote=“Elle, post:9, topic:3320”]
Without intent tables, you will never have perceptual intent or saturation intent as actual choices, instead you’ll get relative colorimetric intent.
[/quote]I didn’t know that. I expected them to be derived from the matrix if that’s all that’s provided but clearly that’s not true. Thanks for the clarification!

It helps. Thanks.
But doesn’t completely eliminate the problem.

That’s an interesting idea, sort of a “smart” color management for constructing perceptual intent tables “on the fly”, perhaps based on the image’s actual colors and the color gamut of the intended output profile. So maybe the software would make an intermediate LUT profile to compress the source colors to fit into the destination color gamut, and then convert from the image to the LUT profile, and then from the LUT profile to the output profile. Various ideas for “smart” color management have been tossed around, I think this is one of them. Though I’m not sure I like the idea of my color management software making artistic decisions for me (like what to do with an out of gamut color).

What a lot of people don’t realize (well, I didn’t realize it until I started experimenting with making LUT profiles using ArgyllCMS) is that making a LUT profile does require having a source color gamut (an image or an RGB working space) and also the destination color gamut. So any colors in the image that exceed the colors in the source color gamut (that was used to make the destination LUT profile’s perceptual intent table), are still clipped.

My apologies, the above is a bit of a mis-statement in that using the chromatic adaptation slider (which is a feature in LCMS2, but not a required feature for V4 color management implementations) isn’t the same as requesting absolute colorimetric intent. But functionally it works in somewhat the same way, except it allows for partial chromatic adaptation. This is something that I don’t have any personal experience using and I’m not sure what the use case would be in a normal photographic workflow.

I’m working on a color adjuster thingy that preserves the CIECAM attributes while letting you adjust one, such as rotating the Hue. Since not all hues have the same chroma range, I quickly exceed the sRGB gamut. I wrote a really naive loop to bring these colors back into gamut “intelligently” by reducing chroma by 1%, and if that doesn’t work, reducing brightness by 1% (that was bad). If after 100 loops I’m still out of gamut, I give up. Maybe @elle or someone can suggest a smarter way?

https://github.com/briend/mypaint/blob/HCYtools/lib/color.py#L1068-L1089

Maybe @jdc can answer?

The gamut control problem is something complex, but basically there are two types of solutions.

  1. the first is to use internal functions in LCMS color managers, or similar. These systems are
    _ simple to use, but suppose I think a certain homogeneity of disparities

  2. the second is to develop specific modules that take into account, for each pixel, the real value of Hue, Chroma and Luma and compare it to the limits of each profile (sRGB, Adobe, Prophoto …)

It is this type of product that I implanted in RT, 6 years ago now.
The system goes through several Lab <==> RGB conversion and uses something that looks like relative colorimetry
In addition, a Munsell correction is performed when there is a significant change in saturation (chroma), to put the colors in the correct values (purple blue, red yellow, etc.).

I’m not saying it’s perfect, but in the case of RT it works.

here is the part of the code where this is implanted

color .txt (223.4 KB)

Jacques

1 Like

Thanks @jdc. It sounds like my approach is at least somewhat rational then. I suspected approach #1 wasn’t right since it would be somewhat defeating the purpose of doing the adjustments in CIECAM in the first place. Fortunately in my implementation I’m not dealing with an entire image, just one color adjusted to another, so I don’t need to worry about the relationships with every other pixel in the image.

There’s a lot of discussion of manipulation to cope with the thread topic, but it seems to me, and correct me if I’m wrong, that the place to start is with preserving the captured gamut as long as possible:

  1. Start with a raw image with an assigned calibrated camera profile. Unless I’m totally out to lunch on this, a profile that accurately describes your camera’s color gamut gives the downstream software an ample playground, so to speak.

  2. Convert the image to a wide-gamut working profile for editing. You may lose a bit of color gamut in a particular direction, but you want the perceptual range and limits to be “well-behaved”, in @Elle’s parlance, for manipulation.

  3. Only at output for a specific medium do you convert the image to a color profile that describes that medium’s gamut capability. This way, you preserve as much color gamut as possible for the medium’s intent transformation.

Starting with sRGB-chopped data seems to just arbitrarily eliminate whole swaths of color range from the git-go, eliminating the opportunity to make good gamut-chopping decisions for the particular output. And, I may be off-base on this, but attempting to recover gamut from the results of a particular operation seems to be about re-creating data you already had. So, work on keeping it, first…

Okay, just read what I wrote, and I want to make sure it’s all open for robust criticism. I’m just learning all this myself, and am by no means an authority. So, in a way, the above is also a, “this is my understanding to date, course-correct me at will” post…

Thanks Glenn, I think I sort of hijacked this thread a bit. I’m not working with a “captured” image/photo/raw file. I’m tweaking an sRGB painting progam (MyPaint). So I’m taking an sRGB color (a selected brush color) and converting that to CIECAM values, tweaking one or more CIECAM dimensions, and taking that new CIECAM color back to the sRGB gamut by reducing the Chroma (if necessary).

Ah, need to read the whole thread… :smiley:

Yes, I’m not sure where to go with your particular canvas, so to speak. I do appreciate the opportunity to write what I did, however; it helped me coalesce some of the concepts I’ve struggled to grasp of late into a bit of understanding.

Back to the current programming…

1 Like

I updated my logic to just 10 iterations and using an exponential reduction method that seems to very quickly find a very close match even if the original color is wayyyy out of gamut:

https://github.com/briend/mypaint/blob/HCYtools/lib/color.py#L1087-L1114