I’m trying to implement a kind of vibrance algorithm, i.e. enhancing the colorfulness of an image by multiplying the chroma channel with respect to color and degree of saturation. Most vibrance functions like the one in Lightroom reduce the amount of enhancement for skin tones to avoid overprocessed results. Skin tones usually are on the yellow, orange,red spectrum, i.e. somewhere between 345 and 75 degrees on hue. Of course this needs more tweaking, but for a start to get a working function it is o.k.
I converted the image to LCH and tried to implement it with fill, but it is not working. The colors are completely off…
From the G’Mic reference I got this information: iN: N-th channel value of current processed pixel
The example there shows it for RGB, where i0 is R, i1 is G and i2 is B.
But in LCH colorspace it is not working. It seems that i0 is here G and not L, i1 is R and not C and i2 is still B and not H. I’ve tested a little bit around with functions like -fill[0] [i0*0,i1*1,i2*0] and it seems to proof my assumption.
WIth rgb2lch, the h is specified in radians, not in degree, so the range [75,345] must be compared with the equivalent amount in degrees.
If the expression provided to fill returns a scalar value (as it is the case in your expression), then it will be evaluated for all channels of the image, which is not want here. Here, you want the expression to be evaluated only for each point (x,y,z). So your expression should return a RGB (i.e. vector3()) instead.
Thus, I propose this:
rgb2lch. f. "[ i0,(inrange(i2*180/pi,75,345)?1.5:1.1)*i1,i2 ]" lch2rgb.
which should do what you want (if I’ve understood it correctly).
You’re on the right direction with the observation of how math parser treat the last value as the value to insert on the image, and vector is one way to do it.
Also, I would consider using sh. 0,2 rgb2lch. rm. because rgb2lch erase alpha channel which is exactly why my code uses shared when converting to a color space model.
Yes, your solution is working as expected. I still need to tweak the parameters, but the functionality is there.
I was on the right track, but I didn’t know about the radians for LCH hue and the use of square brackets for a vector. There is still a long way to learn G’Mic, but it’s a great tool!
@Reptorian: Thanks for the hint with the alpha channel, but fortunately my images have none.
If you are using fill, the 3 channel image vector is [ i0, i1, i2 ] or [ R G B ]. It could be RGB or L*C*h°: i0 or R would represent the first channel and so on. There is a lot you can do within fill (the math interpreter). E.g.,
fill "
L = i0/2; # pre-calculate
[ L, i1, i2 ]
"
fill "
[ B, G, R ] # reorder or duplicate channels
"