Help: How to achieve "Vibrance"?

Here:

gmic sp elephant srgb2rgb +store. img rgb2hsv sh 1 mul. 0.8 rm. hsv2rgb rgb2srgb $img a x d0

I think your $img is in linear rgb there, that’s probably why…

Yeah, that’s a good explanation. I fixed it, and I got this result (modified mul to .5):

It looks pretty convincing.

1 Like

Here the vibrance for g’mic to use in the various - custom code global

-fill vibrance=1.00;i0=i0/255;i1=i1/255;i2=i2/255;min=min(i0,i1,i2);lum=(i0*0.2+i1*0.7+i2*0.1);sat=1-(min/lum);sat=if(sat>1,1,sat);sat=if(sat<0,0,sat);i=i/255;ii=(i-lum)*vibrance+lum;i=(ii*(1-sat)+i*sat)*255

Vibrance is the only parameter to modify, value >1 will increase the vibrance

The code is just an inverted saturation mask (it leaves the"luminance channel" untouched)

In gimp we could extract the saturation channel

Invert it

Use his layer as a mask and increase the saturation

If we want to decrease the vibrance the saturation channel should not be inverted.

8 Likes

There is an easy way to create a vibrance preset in GIMP.

Creating a vibrance preset in GIMP

  1. Open the hue saturation tool.
  2. Set the saturation to 100 for the G,C, B and M colours only. (Y and R stay at 0.0)
  3. Set the overlap to 15
  4. Save as a preset called Vibrance.
  5. When recalling this preset to use on an image, the strength can be controlled by adjusting the opacity slider in the hue-saturation tool.
1 Like

I’ll make a filter Color / Vibrance from this.
What name can I use to credit you?

1 Like

@age , I wrote this, from your code.
The filter manages a split preview as well as images with alpha channels:

#@gui Vibrance : fx_vibrance, fx_vibrance_preview(1)+
#@gui : Strength = float(1.5,0,4)
#@gui : sep = separator()
#@gui : Preview Type = choice("Full","Forward Horizontal","Forward Vertical","Backward Horizontal",
#@gui : "Backward Vertical","Duplicate Top","Duplicate Left","Duplicate Bottom","Duplicate Right",
#@gui : "Duplicate Horizontal","Duplicate Vertical","Checkered","Checkered Inverse")
#@gui : Preview Split = point(50,50,0,0,200,200,200,0,10)_0
#@gui : sep = separator()
#@gui : note = note("<small>Author: <i>Age / Pixls.us</i>.      Latest Update: <i>2022/06/28</i>.</small>")
fx_vibrance :
  foreach {
    split_opacity l[0] {
      to_rgb
      f "const vibrance = $1;
         vib(val) = (
           v = val/255;
           vv = (v - lum)*vibrance + lum;
           (vv*(1 - sat) + v*sat)*255
         );
         min = min(R,G,B)/255;
         lum = (R*0.2 + G*0.7 + B*0.1)/255;
         sat = cut(1 - min/lum,0,1);
         [ vib(R),vib(G),vib(B) ]"
      }
      a c
    }

fx_vibrance_preview :
  gui_split_preview "fx_vibrance $*",${-3--1}

I’ve already pushed it in the filter updates, so it should be available for all users of G’MIC 3.1.3+.

Just let me know about your preferred way to be credited.
Thanks! :beer:

6 Likes

In the darktable “color balance rgb” module, there is a slider “global vibrance”. I used the middle column (original) of the posted example and opened it in darktable 3.8. Besides “color balance rgb” I only activated filmic rgb with default settings.

The result below is in no way identical to the posted example but quite similar.

1 Like

Hi thanks David I’m fine with my forum’s username :muscle:t2:

1 Like

Perfect! Thanks again! I’ve posted a tweet about this :slight_smile:

3 Likes

I noticed, and he gave me his code. Based on the code provided by the person I mentioned (shame to see him go), I have made my translation for G’MIC. It’s the same except for chroma boost.

#@cli rep_ych_vibrance: 0<vibrance<=1
#@cli : Increase Chroma of Image with minimal to no impact on high-chroma areas. Based on Darktable YCH "Vibrance" code.
rep_ych_vibrance:
vibrance={cut(abs($1),0,1)}
if !$vibrance return fi
foreach {
 if s<3||s>4 continue fi
 if s==4 sh. 0,2 fi
 rgb2yiq.
 sh. 1,2
 f. "
  V=I;
  [norm(V),atan2(V[1],V[0])];"
 sh. 0
 f. "begin(
   const vibrance=$vibrance;
  );
  v=vibrance*(1-i^vibrance);
  chroma_factor=max(0,1+vibrance);
  i*chroma_factor;"
 f.. "
  polar_coordinates=I;
  r=polar_coordinates[0];
  ang=polar_coordinates[1];
  [r*cos(ang),r*sin(ang)];
  "
 k[0]
 yiq2rgb
}

This one utilize the YCH model instead of RGB model.

I noticed some details may be lost on images with already high chroma, I think that’s my fault, but oh well.

Also, I can’t tell what’s better at times. The RGB approach or the YCH approach. YCH is worse on green, but RGB is worse at other colors. I will say that YCH approaches preserve some information better, and is generally a improvement in some case.

EDIT in 6/29/2022: Polar version of YIQ is better than YUV according to my recent experiment.

2 Likes

Curious: did you convert from/to sRGB? I usually don’t because I am lazy.

Thanks @Reptorian , I move it from Testing/ to Colors/.

2 Likes

Now, I just did, but decided to go through srgb2rgb, and then rgb2srgb as that seem to preserve information some more. I also added better weighing. It still has color bleed, but that probably because of the out-of-gamut issue, and at that point, I don’t think I can do much more.

There seems to be no option to reduce Vibrance?

I’ll add it in a few, it isn’t much to do.

Note that tomorrow, I’m going on vacations for one week. There won’t be any filter update during this period (computer at the lab is powered off).

1 Like

I have made some changes. It’ll be here next week:

1 Like

Earlier in this thread I mentioned a GIMP plug-in I had created.
I have now made a simplified version that makes it possible to increase or reduce the saturation in both the high and low saturation regions of an image. It also runs somewhat quicker (but still slow, because it is written in Python 2.7xx).
It creates two masked layers above the original, one of which contains the high saturation parts, the other the low. After adjustment the layers can be merged down.
I have also “stretched” the mask in the hope that it will give a usable amount of change where the saturation range of the original image is small.
I have attached it here and hope to receive comments, suggestions and criticism!

vibrance.py.zip (1.3 KB)

2 Likes

After testing some more of Vibrance / Vibrance [YCH], and working on Vibrance [YCH] (Note that G’MIC can’t be updated during this week). It seems that Vibrance [YCH] actually preserves perceptual luminosity better than Vibrance. I actually have compared it with Ed’s Harvey Vibrance plugin for Paint.NET.

I ranked from best to worst:

  1. Ed Harvey’s Vibrance - This preserves luminosity better than Vibrance [YCH], but it isn’t that much better. And also preserves saturation better at 100%. Sometimes this performs worse than Vibrance[YCH]. Basically 52/48.
  2. Vibrance [YCH] - Performs a slightly worse than the above. However, extremely close to the above, so they’re interchangeable, and there are few cases where this is better than the above. Clearly need of a improvement.
  3. Vibrance - This one has glaring issue with really high chroma image on high vibrance.

What I think that may improve my Vibrance [YCH] is either switching to a different color space, or modify the YUV color space so that it matches one of the gmic rgb2lab illuminant. There’s another possible way to make it better, a modified version of rgb2srgb/srgb2rgb. Or even both. That way, we finally have a proper Vibrance filter as luminosity would be better perserved in some areas. However, improvement could mean trying to grasp it and then finding a better mathematical model.

Here’s the test results for all Vibrance filters.

1st image - No filter
2nd image - Ed’s Harvey’s Vibrance for Paint.NET
3rd image - G’MIC Vibrance [YCH]
4th image - G’MIC Vibrance

You can clearly see why I ranked it like this after you zoomed onto the rooster’s head.

2 Likes