ilia3101 / MLV-App

All in one MLV processing app.
https://mlv.app/
GNU General Public License v3.0
289 stars 31 forks source link

Add HSL elements #137

Closed masc4ii closed 5 years ago

masc4ii commented 5 years ago

In Lightroom there are these HSL sliders. I tried to create something, what is able to do the same, but what is easier to use. Here the example for Hue vs. Luma, I also got it drawn for Hue vs. Saturation: bildschirmfoto 2018-12-03 um 20 01 16

I tried to implement also the processing functions (as prototype). But here I got problems. I found RGB2HSL and HSL2RGB here (and changed it to 16bit RGB): https://www.programmingalgorithms.com/algorithm/hsl-to-rgb?lang=C%2B%2B https://www.programmingalgorithms.com/algorithm/rgb-to-hsl The conversion works so far - that means, converting and converting back brings the same picture like without conversion. But if I try to select some pixels by Hue value and change their Luma or Saturation strange things happen.

Testcode for lowering the luma by 20% between red and yellow:

for (uint16_t * pix = img; pix < img_end; pix += 3)
    {
        float hsv[3];
        rgb_to_hsl( pix, hsv );

        if( hsv[0] > 0 && hsv[0] < 60 )
        {
            hsv[2] *= 0.8;
        }

        hsl_to_rgb( hsv, pix );
    }

m23-1205_frame_1

Or lower luma from cyan to violett by 20%:

for (uint16_t * pix = img; pix < img_end; pix += 3)
    {
        float hsv[3];
        rgb_to_hsl( pix, hsv );

        if( hsv[0] > 180 && hsv[0] < 285 )
        {
            hsv[2] *= 0.8;
        }

        hsl_to_rgb( hsv, pix );
    }

m23-1205_frame_1

In both pics, see the mountains... I'll need some help here! :-) Someone likes to help?

Edit: Doing some smoother functions (a triangle, before it was just a square) and it looks better. But is it good to multiply something onto the luma? See all the artifacts everywhere in the sky and on the buildings:

for (uint16_t * pix = img; pix < img_end; pix += 3)
    {
        float hsv[3];
        rgb_to_hsl( pix, hsv );

        if( hsv[0] > 180 && hsv[0] < 240 )
        {
            hsv[2] *= 0.8 + ( 0.2 * (fabs(210-hsv[0])/30.0) );
        }

        hsl_to_rgb( hsv, pix );
    }

m24-1153_frame_1

bouncyball-git commented 5 years ago

Oh, ugly artifacts indeed.

masc4ii commented 5 years ago

bildschirmfoto 2018-12-05 um 22 46 40

Cosine interpolation... in da house!

bouncyball-git commented 5 years ago

Does it work? Wanna try :P

masc4ii commented 5 years ago

It is just GUI only for now. I'm gonna keep tinkering tonight.

bouncyball-git commented 5 years ago

BTW that cosine interpolation can be useful for gradation curves?

masc4ii commented 5 years ago

Not really. Gradation curve needs cubic interpolation (mathematical derivation != 0 in each point) and for HSL curves mathematical derivation needs to be 0 in each point, and lines in between have to be independant. That's the reason for 2 different interpolation methods.

bouncyball-git commented 5 years ago

Thanks for info :)

masc4ii commented 5 years ago

bildschirmfoto 2018-12-06 um 21 53 40

Now you can test. It is not ready yet. See commit for some more comments... Quality is a bit better now, because I change luma level in dependency to saturation. This brings less artifacts... Therefor there seems to be a problem, when raising luma for a color now... brings colorful artifacts. Funny.

Change new code in raw_processing.c to this, to get HueVsSat:

//Testcode for HueVs...
    if( processing->hue_vs_luma_used )
    {
        for (uint16_t * pix = img; pix < img_end; pix += 3)
        {
            float hsl[3];
            rgb_to_hsl( pix, hsl );

            uint16_t hue = (uint16_t)hsl[0];
            hsl[1] += processing->hue_vs_luma[hue];//*hsl[1]*2.0;
            if( hsl[1] < 0.0 ) hsl[1] = 0.0;
            if( hsl[1] > 1.0 ) hsl[1] = 1.0;

            hsl_to_rgb( hsl, pix );
        }
    }
bouncyball-git commented 5 years ago

Artifacts are very ugly, all over the image ugly dots dots dots :astonished:

masc4ii commented 5 years ago

I only get dots on moiree artifacts. No idea how to filter them. In past I had exactly the same with the vibrance slider but got it fixed (there was a wrong condition in "current saturation" (before applying) calculation). Here there is different code... have to look into that. Maybe these rgb2hsl and hsl2rgb functions are not correct (copied from somewhere).

bouncyball-git commented 5 years ago

Well, I have to correct myself. It gets more ugly with noisier images. sidecar_frame_1 sidecar_frame_2 Other than that with good image it does the job.

I HATED!!! color noise since my 1st VHS camera ;)

bouncyball-git commented 5 years ago

Another example. Look at water surface. m04-1040_frame_325

masc4ii commented 5 years ago

Japp, right. In the end it is very similar as the old vibrance problem. In the first version where this was included, it looked the same.

bouncyball-git commented 5 years ago

We could try to make thing like this:

When staying over created point on a Hue vs Luma curve rotate mouse wheel or click and hold right mouse button and then drag the mouse pointer. This will change 3rd dimension of this point which can be the Saturation. This means we could have 3d curve Hue vs Lightness vs Saturation. Interpolate these points for example with 3D Hermite Interpolation:

/*
   Tension: 1 is high, 0 normal, -1 is low
   Bias: 0 is even,
         positive is towards first segment,
         negative towards the other
*/
double HermiteInterpolate(
   double y0,double y1,
   double y2,double y3,
   double mu,
   double tension,
   double bias)
{
   double m0,m1,mu2,mu3;
   double a0,a1,a2,a3;

    mu2 = mu * mu;
    mu3 = mu2 * mu;
   m0  = (y1-y0)*(1+bias)*(1-tension)/2;
   m0 += (y2-y1)*(1-bias)*(1-tension)/2;
   m1  = (y2-y1)*(1+bias)*(1-tension)/2;
   m1 += (y3-y2)*(1-bias)*(1-tension)/2;
   a0 =  2*mu3 - 3*mu2 + 1;
   a1 =    mu3 - 2*mu2 + mu;
   a2 =    mu3 -   mu2;
   a3 = -2*mu3 + 3*mu2;

   return(a0*y1+a1*m0+a2*m1+a3*y2);
}

Editing directly like with 3D Lut.

masc4ii commented 5 years ago

I planned to edit hue and saturation with further diagrams. HueVsSaturation is done now. And HueVsLuma works better now too (at least for my testclips). Try out.

masc4ii commented 5 years ago

bildschirmfoto 2018-12-07 um 17 00 13

masc4ii commented 5 years ago

Adobe seems to have the same problems and uses a blur on the edited areas (see the sky): bildschirmfoto 2018-12-07 um 17 15 56

bildschirmfoto 2018-12-07 um 17 18 50

bouncyball-git commented 5 years ago

H vs S Works great! m04-1040_frame_320

bouncyball-git commented 5 years ago

Did you also blur H vs L processed areas? It looks lot more better.

masc4ii commented 5 years ago

No, I tried some different math... I now multiply instead of add/subtract, so it works in relation what was before -> artifacts are not amplified.

bouncyball-git commented 5 years ago

Do not get the meaning of "in relation what was before", but it really helps a lot :)

masc4ii commented 5 years ago

Before:

hsl[2] += processing->hue_vs_luma[hue] * sat * 2;

Now:

hsl[2] *= 1.0 + (processing->hue_vs_luma[hue] * sat * 2);

masc4ii commented 5 years ago

Hue vs. Hue working... yeay. bildschirmfoto 2018-12-07 um 19 57 05 Now doing this into receipt...

masc4ii commented 5 years ago

Btw: should we create a new tab "HSL" for these 3 curves, or is it okay in Processing tab?

masc4ii commented 5 years ago

Now we have full receipt support for HSL curves.

bouncyball-git commented 5 years ago

I think it deserves separate section. It is more on color correction side.

bouncyball-git commented 5 years ago

Overall... GREAT job MAN! 😁

masc4ii commented 5 years ago

So I'll add a new Groupbox for it. In Processing tab there are too many elements now, I think too.

bouncyball-git commented 5 years ago

When mouse leaves area accidentally the point deleted and annoying behavior happens.

I just wanna ask you to disable deleting point when mouse leaves the working area in all 3 editors. Just do nothing and leave the dragged point at the edge of the area where mouse crossed the border. I think it will be more comfortable.

masc4ii commented 5 years ago

When mouse leaves area accidentally the point deleted and annoying behavior happens.

I just wanna ask you to disable deleting point when mouse leaves the working area in all 3 editors. Just do nothing and leave the dragged point at the edge of the area where mouse crossed the border. I think it will be more comfortable.

Done.

And HSL Groupbox: also done.

bouncyball-git commented 5 years ago

Cool! Thanks! I'm out of reach of any PC now... will check it tomorrow at work.

bouncyball-git commented 5 years ago

It just fu..n works! Thanks!