Photo post / audio analogy - de-yellow night shot

Personally, I prefer the monochrome versions. Second best, I like the yellowish cat and rocks with electric blue background. That has a kind of dreamy quality, as if the background has been invented by the cat, and projected into our eyes by that intense stare. The car almost sits like a toy on the stone wall.

And I won’t comment on the blue spotlight on the cat’s, umm, nether regions.

Anyhow, let’s treat this as an exercise. Remove the overall orange colour cast by multiplying the Red channel by the average Green and dividing by the average Red, similarly B = B*average(G)/average(B). Also find the average color of the light chest fur. Windows BAT scripts, using ImageMagick:

rem This is the crop for the cat's fur.
set sCROP=-crop 115x87+627+486 +repage

for /F "usebackq" %%L in (`%IMG7%magick ^
  %SRC% ^
  -colorspace RGB -set colorspace sRGB ^
  ^( +clone ^
     -scale "1x1^!" ^
     -set option:FR %%[fx:u.g/u.r] ^
     -set option:FB %%[fx:u.g/u.b] ^
     +delete ^
  ^) ^
  -channel R -evaluate Multiply %%[FR] ^
  -channel B -evaluate Multiply %%[FB] ^
  +channel ^
  -set colorspace RGB -colorspace sRGB ^
-define "quantum:format=floating-point" -depth 32 ^
+write x.miff ^
  +write x.jpg ^
  %sCROP% ^
  -scale "1x1^!" ^
  -format "COL=#%%[hex:p{0,0}]" ^
  info:`) do set %%L

echo COL=%COL%

COL is #7E4E99CE7A9EBF9E5E046B04, or roughly #7E7B5E.

As I say, I like this intermediate result, x.jpg:


Here comes the clever bit. Transform to a new colorspace with 2 colour channels and a lightness channel. Channel 0 is the “yellowness/blueness” where yellow is the hue of the average colour in the patch of fur. Channel 1 is the orthogonal colour channel. Channel 3 is lightness. The colorspace is defined by a matrix from sRGB:

  0.295412, 0.204585, -0.5
  -0.429262, 0.5, -0.0707384
  0.2, 0.7, 0.1

(I haven’t yet published the software that calculates the matrix, the process module “colsp012”.) The inverse matrix, from the new colorspace back to sRGB, is:

  0.422527, -1.57289, 1
  0.122187, 0.550004, 1
  -1.70036, -0.704252, 1

Values can be negative. We adjust channel 0 to push values towards zero. We could simply multiply by 0.25 or whatever, but I prefer an S-curve, which mean first adding 0.5, applying an S-curve centred at 0.5, then subtracting 0.5.

%IM7DEV%magick ^
  x.miff ^
  -process 'colsp012 color %COL% f stdout v' ^
  -channel 0 -evaluate Add 50%% -clamp +sigmoidal-contrast 10,50%% -evaluate Subtract 50%% +channel ^
  -process 'colsp012 color %COL% inverse f stdout v' ^
  x1c.jpg

x1c.jpg is:

3 Likes

Thanks @snibgo for letting me bother you about white balancing.

No bother, @afre. Anytime.

Above, you said “I ended up guided filtering the GB channels with R.” Can you expand on that? What product(s) did you use?

I ask because I have just written a script for guided filters, and am still playing with it.

My command is as follows

gmic cat.jpg split c afre_gui1[1,2] [0],1,1e0,0 append c cut 0,255

Indices 0,1,2 correspond to RGB channels respectively. I am using the R channel because it contains the most info as shown in post #10.


Take 2. Same algorithm but with different ratios and less code. This one doesn’t produce the magenta but neutralizes it. Still doesn’t look quite right.

PS Part of the problem might be neglecting to convert sRGB to linear RGB…

Tim, the number of adjustments you made in channel mixer to find the right combination is a testament to your patience and perseverance. Your directions give justice to the statement, easier said than done! :ok_hand:

I am a patient man, but I don’t actually recall this taking too long. It is quite simple to make r = g = b, the only tricky part is determining which slider in which channel to adjust to achieve natural looking colours. There was some trial and error involved in that.

Perhaps it is more to do with ones comfort level using the channel mixer. It used to be completely foreign to me, but I’m beyond the beginner stage now and its not as scary.

Manual tweaking while taking more time and effort does do better than auto-magical results, as can be seen when comparing @a286’s to mine.

This is a great exercise, especially when you limit yourself to using only the channel mixer. This would include setting your brightness, which makes this (a lot?) harder to do due to this being an RGB model tool where brightness and saturation are linked (unlike the L*a*b model, where luminance and chrominance are fully separated).

I find this part to be true, although comfort level using a specific tool does come into play.

@Underexposed
If you let go of the R=G=B needs to be a specific number requirement and fall back to the R=G=B need to be the same while inside the channel mixer, 'cause you change brightness/luminosity much easier/better using other tools, this becomes easier to do.

The actual R, G and B numbers become a guide to which colour needs adjusting. Starting with the most dominant colour (orange-> RED in the cat example) and just using the major channels (red in R, blue in B), you can initially ogle it. For the fine-tuning you need to use the secondary channels and now the numbers are needed to get to R=G=B.

I personally try to stay away from the G channel, if at all possible. I see this as an anchor and noticed that changing these have a big(ger) effect on the R and B channels. This isn’t always possible though, but keep the changes as small as possible.

You could ditch the channel mixer altogether and try doing this with the RGB curve tool using independent channels and the help of its picker :laughing:

I didn’t see it as any more difficult. Instead of saying ‘I want to remove orange cast’ and thus reducing predominantly red and secondarily green, you can say ‘I want to add teal cast (opposite of orange)’ and thus increase predominantly blue and secondarily green. @afre’s post giving the greyscale of each channel gives us the clue why. You could achieve r=g=b either way, but the former would be dark, while the latter would be bright. That’s why I started by determining which channel I wanted the brightness of - R - and matched the others - B and G - to it.

Yes in most cases G will have the best information, but not so in this example, under very orange light.

There are many ways to (colour the) skin (of) a cat. :laughing:

With the “cat image”, I would do something like this with G’MIC:
First G’MIC>Colors>RGB Tone

[G’MIC] RGB tone: iain_rgb_tone -47.94,-32.13,-48.96,0.51,-3.57,41.31,-6.63,-4.08,4.08,-27.03,-15.3,-2.04,4.59,-8.16,-21.42,0.51,14.79,-9.18,-62.22,9.18,79.56,-30.6,15.3,51,10.71,19.38,27.03,255,255,255,255,255,0


The cat has a magenta tint now.
Therefore I use G’MIC>Colors>HSL Adjustment:

[G’MIC] HSL Adjustment: gcd_hsl 0.916,-0.13,0,207.36,0.079,0,1,1,0


Thereafter a final correction (assumed the cat’s fur and car tire are gray) with G’MIC>Colors>Curves:

1 Like

@Soupy
Heh. There were 69 steps in that history list, although once you settled on just channel mixer in step 40, it took only 27 more adjustments to get where you wanted it.

@Jade_NL
Besides using color picker, I have the histogram set for waveform RGB parade. I find both useful for getting the channels equal. However, many times I had them equal and still had blue instead of gray on the cat’s belly.

Soupy didn’t use brightness but still got a well exposed image by the level of RGB he used. I played with brightness, but still didn’t get around the blue belly problem.

I also tried using just color balance, but it took channel mixer to get free of the yellow.

channel mixer rgb offers the ability to normalize the channels. I have tried that and struggled just as much as without it to get the desired result. If I understand right, using it maintains the gray level. Is it worth it?

I don’t understand why you make things complicated. It is just to to add the complementary color

Sure, but I posted two different versions in this thread. The first version I was playing around with a combination of color balance, channel mixer, and color zones. That was 26 steps in the first xmp, so the second version was more like 40 adjustments - a couple of which are simply resetting and turning off what I did in the first version to start over. As I said, most of the adjustments were trial and error to reach the correct values - I didn’t do it mathematically I was just moving sliders a little this way, a little that. It could be done mathematically, but I am not a mathematician at heart, and it’s not very time consuming to just eyeball it. I knew what I was aiming for and how to get there (r=g=b), but didn’t know exactly which slider (r,g, or b) in each channel would get me the most natural looking result, so I compared them. If I was more advanced, that’s the kind of thing I’d probably just know immediately. I think I was playing around with blending at some stages too - an unnecessary thing that was just for my own experimentation. I wasn’t treating it like a race. Placing too much emphasis on the history stack can be misleading, as it doesn’t tell you which parts were for my own fun, and which parts were to achieve a result.

From Aurelien’s introducing color calibration,
“This also introduces much requested normalization options, that will keep the sum of parameters to 1”

I haven’t used the new module yet, but my understanding is when normalization is ticked R+G+B = 1 for that channel. This ensures greys stay grey, which is desirable when you have neutral grey to start with (and you want to keep them that way). But in the cat image we don’t have neutral grey to start, we have strong orange cast, so you should leave normalize unchecked.

@Soupy I’m not criticizing, just emphasizing your persistence. Remarkable. You found a really good combination of settings.

That’s a good point.

I used neutralize colors in color balance, once, then, twice, then a third time, but it didn’t get rid of the yellow entirely. Plus, I tried to do it manually, using dt, for quite some time, but couldn’t get rid of the blue belly. You’re using ART, and it seems to be easier with ART. I tried the 1800 degrees in white balance, but that was way off in dt. Channel mixer was the way to go, and I made several attempts at it to try to develop some feel for what would happen when I moved a slider. I have made some progress learning how to get two spots equalized. Then I made life difficult by trying to do that with three spots. Not able to equalize all three, but came close enough, and I got better at it.

Thanks Bill. I didn’t read it as criticism, but even if it was I wouldn’t have a problem with it - I’m more of a ‘critique’ guy than a ‘showcase’ guy - more opportunity to learn.

I quickly made a haldclut to get rid of the cast and played with it (neutral profile)

I read about haldcluts on RawPedia. I would have to do a lot more studying to understand what you did. What puzzles me at the moment is how the yellow is taken away while at the same time the blue belly is corrected. Seems like opposing processes, but it does it all at once.

dt’s color balance tries to take away the yellow, but only partially does so, and affects a slight amount of the blue belly. Of course, I have been trying to do correction without masking.

To generate the Haldclut:

  • neutral profile with photo
  • I used the ART/ local editing/color/tone correction/color wheel to add the orange complementary color and going a little to far to get a light blue cast. This is like subtracting the orange cast. No mask
  • generate an ARP file
  • load the haldclut identity tiff photo, apply above ARP, generate a PNG 8 bits, rename, put in my haldclut custom files. done.

Using the ARP and the haldclut 100% give the same output.

The interest of the Haldclut is that you can modulate the correction. That can surely be done with layers in DT.

Playing other ways with WB, color mixer and so on, did not permit me to get the same result with so little effort. And as you I am surprised.