# Why do pure colors (red/green/blue) become a mixture of colors when converting raw?

In trying to understand how raw is converted, I created a synthetic raw image that has a red, green and blue gradient strip, with a gamma of 2.2 (dng). I made the synthetic raw by converting an image from a Nikon D200 to uncompressed DNG, then overwriting the image data using python.

When I convert it to jpeg, I would expect it to retain the pure colors, like the image below:

I then used lightroom and lightzone to convert this image to jpeg with default settings and white balance set to daylight. These are the results, where especially the red and blue contain other colors and their own.

Lightroom:

Lightzone:

My understanding of white balance was that it was just a number to multiply each color by, but not mixing them. That appears to be wrong. Can anyone explain why the colors do not remain "pure"?

• Applying white balance to an image composed of pure (as in single non-zero R, G or B component) will almost always result in non-pure colors, as the effect of white balance is to subtract (or add, depending how you look at it) a specific color cast to make it warmer (more red/orange/yellow-ish) or cooler (more blue/violet-ish) as well as adjust green-magenta balance. Any of these is a color correction that will convert your "pure" colors to non-"pure" colors. It sounds to me you were thinking of white balance more along the lines of a tone curve or gamma... – twalberg Aug 6 '19 at 16:54
• It's true that one adds and subtracts colors when you have already chosen a white balance, but why does this also happen for a raw image? I thought white balancing a raw was just to use math to convert a temperature in K to multipliers for linear r, g and b. Do you know a resource that explains something else? – Atnas Aug 6 '19 at 17:25
• Make sure this isn't a color-space problem. – feetwet Aug 6 '19 at 18:32
• It's a mistake to think of the R,G, or B values in a camera RAW file as "pure" colors. Not only aren't they, but they can't be. – doug Aug 7 '19 at 3:21

Here are some causes for non-zero values that you expect to be zero. The most relevant to your problem are listed first.

• Your synthetic raw does not account for the input color profile of the camera, which is based on how the specific colors filter in the Bayer matrix interact with lighting sources when photographing calibration targets (with a lens, which may have its own color shift). Here is the histogram and output with the D200 profile (using RawTherapee):

Compare with when no camera profile is used.

See RawPedia: What Are DCP Profiles and Why Do I Need Them?

• Some people refer to how manufacturers design their cameras to render colors to deviate from "reality" in a pleasant manner as their "color science".

These are configured in cameras via settings often labeled "color profiles" or "film simulations". They often have names such as Standard, Neutral, Vivid, Portrait, Landscape, and Flat. Some raw processors may attempt to replicate these profiles in a layer of color modification separate from color-correction profiles, camera input color profiles, and color spaces.

• The working color space may not match the output color space. Make sure the working and output color spaces match. If that is not possible, selecting a different conversion method may produce "better" results because out-of-gamut colors are converted differently by different algorithms. Here are histograms to illustrate:

• sRGB → sRGB:

Less relevant possibilities:

• Highlight Recovery using CIELab Blending can affect the colors at the bright end of the gradients. Other methods (Blend, Color Propagation, and Luminance Recovery) had no apparent effect on the gradients.

• The demosaicing algorithm can affect interpretation of colors.

See RawPedia: Demosaicing

• Some programs add noise or dithering when converting color from higher bit depths to 8-bit/channel.

... the red shift is towards the actual color of the "red" filter in a typical Bayer mask - somewhere between yellow and orange. – Michael C

Ideally, "pure" input colors would result in output colors that match the Bayer filter of the selected camera. However, in practice, that is not what happens.

The color shift appears to be caused by camera profiles used by the raw processors, along with other contributing factors. They are created by processing photographs of calibration targets, taken with real lenses, under different lighting sources, as described at RawPedia. So the color filter does contribute, to the extent that it is involved in profile creation. However, each program produces different output, so it cannot be said which, if any, of them shifted toward, or away from, the actual colors of the Bayer filter used in any particular camera.

Regardless of the actual color in the Bayer array, select a different profile, and the output colors change. Use a different program, which uses different profiles, and the colors change. Use a synthetic profile, and the colors may be entirely unrelated to any real Bayer array.

Yet another layer of color modification that dissociates the actual colors of the Bayer array from the output image is "color profiles", such as Standard, Neutral, Vivid, Portrait, Landscape, Flat, which some raw processors may attempt to replicate.

• My guess for the red-orange shift is that at the saturated end highlight recovery algorithms kick in (in this case, badly, but they're not meant for this contrived scenario). – Please Read Profile Aug 6 '19 at 19:57
• @mattdm Highlight recovery using CIELab blending affects the bright ends of the gradients. The other algorithms don't appear to have any effect on the gradients. – xiota Aug 6 '19 at 21:19
• @mattdm interesting that the red shift is towards the actual color of the "red" filter in a typical Bayer mask - somewhere between yellow and orange. – Michael C Aug 6 '19 at 22:04
• That is all covered by the statement that it is "based on the specific colors used in the Bayer matrix". – xiota Aug 6 '19 at 23:39
• @xiota great explanation. Now I just need to understand how color profiles work :) – Atnas Aug 7 '19 at 9:10