3

I have two images. I have to found the points of first image which have intensity greater than 0.8. At the same time I have to found the intensity of second image on same points and need to adjust the light on second image on same points with a threshold/slider value(ranges from 0 to 1). I have done like below. Getting black or dark area on points have intensity greater than 0.8.  I'm trying with z value of HSV.
But instead of this black area I should be able to adjust the light on image2. How can I achieve this? 

public void CreateShaders()
{
    /***********Vert Shader********************/
    vertShader = GL.CreateShader(ShaderType.VertexShader);
    GL.ShaderSource(vertShader, @"
        attribute vec3 a_position;
        varying vec2 vTexCoordIn; 
        void main() {
            vTexCoordIn=( a_position.xy+1)/2 ;
            gl_Position = vec4(a_position,1);
        }");
    GL.CompileShader(vertShader);

    /***********Frag Shader ****************/
    fragShader = GL.CreateShader(ShaderType.FragmentShader);
    GL.ShaderSource(fragShader, @"
        precision highp float;

        uniform sampler2D sTexture1;
        uniform sampler2D sTexture2;  
        varying vec2 vTexCoordIn;
        const float Epsilon = 1e-10;
        uniform float sSelectedIntensity1;//slider value 0 to 1
        void main ()
        {
            vec2 vTexCoord=vec2(vTexCoordIn.x,vTexCoordIn.y);    
            vec4  color1 = texture2D (sTexture1, vTexCoord);
            vec4  color2= texture2D (sTexture2, vTexCoord);
            vec3  col1_hsv = RGBtoHSV(color1.rgb);
            float col1_intensity =col1_hsv.z;
            float ConstVal=0.8;

            if(col1_intensity>ConstVal)
            { 
                vec3 col_hsv = RGBtoHSV(color2.rgb);
                col_hsv.z *= sSelectedIntensity1;//slider value 0 to 1 
                vec3 col_rgb = HSVtoRGB(col_hsv.rgb);
                gl_FragColor = vec4(col_rgb.rgb, color2.a);
            }
            else
            {  
                gl_FragColor = color2;
            }
        }");
    GL.CompileShader(fragShader);
}

iNput

OUTpUT

Practically, if image1 and image2 are frames coming from two adjusent cameras cam1 and cam2 respectively. And if I put a flash light infront of cam1, i should be able to dim/remove this light effect on frames of camera 2.

H.NS
  • 75
  • 7

1 Answers1

1

If you want to modify the lightness of the color, the you've to multiply with a value in range [0, 2] rather than a value in range [0, 1]. If you multiply with a value in range [0, 1] the result will at maximum be as bright as the source:

col_hsv.z *= sSelectedIntensity1 * 2.0;

If you want to enlighten the image dependent dependent on the "bright" parts of the other image then you've to add a term to the lightness, which depends on the lightness (of the other image) and the slider. e.g.:

col_hsl2.z += (col1_intensity-constVal)*sSelectedIntensity1/(1.0-constVal);

If you want to change the lightness the I recommend to use the HSL (hue, saturation, lightness) color range rather than the HSV (hue, saturation, value.
In compare to HSV, at HSL the 3rd value represents the lightness of the color:

const float Epsilon = 1e-10;

vec3 RGBtoHSL(in vec3 RGB)
{
    vec4  P   = (RGB.g < RGB.b) ? vec4(RGB.bg, -1.0, 2.0/3.0) : vec4(RGB.gb, 0.0, -1.0/3.0);
    vec4  Q   = (RGB.r < P.x) ? vec4(P.xyw, RGB.r) : vec4(RGB.r, P.yzx);
    float C   = Q.x - min(Q.w, Q.y);
    float H   = abs((Q.w - Q.y) / (6.0 * C + Epsilon) + Q.z);
    vec3  HCV = vec3(H, C, Q.x);
    float L   = HCV.z - HCV.y * 0.5;
    float S   = HCV.y / (1.0 - abs(L * 2.0 - 1.0) + Epsilon);
    return vec3(HCV.x, S, L);
}

vec3 HSLtoRGB(in vec3 HSL)
{
    float H   = HSL.x;
    float R   = abs(H * 6.0 - 3.0) - 1.0;
    float G   = 2.0 - abs(H * 6.0 - 2.0);
    float B   = 2.0 - abs(H * 6.0 - 4.0);
    vec3  RGB = clamp( vec3(R,G,B), 0.0, 1.0 );
    float C   = (1.0 - abs(2.0 * HSL.z - 1.0)) * HSL.y;
    return (RGB - 0.5) * C + HSL.z;
}

Use the functions like this:

void main ()
{
    vec2  vTexCoord = vec2(vTexCoordIn.x,vTexCoordIn.y);
    vec4  color1    = texture2D (sTexture1, vTexCoord);
    vec4  color2    = texture2D (sTexture2, vTexCoord);

    vec3  col1_hsl1 = RGBtoHSL(color1.rgb);
    float col1_intensity = col1_hsl1.z;

    float constVal = 0.8;
    if (col1_intensity > constVal)
    {
        vec3 col_hsl2 = RGBtoHSL(color2.rgb);
        col_hsl2.z   += (col1_intensity-constVal)*sSelectedIntensity1/(1.0-constVal);
        vec3 col_rgb  = HSLtoRGB(col_hsl2.rgb);
        color2        = vec4(col_rgb.rgb, color2.a);
    }

    gl_FragColor = color2;
}

An other option would be to modify the lightness of the entire image dependent on the lightness of the other image. In this case there is no need of the factor 0.8:

void main ()
{
    vec2  vTexCoord = vec2(vTexCoordIn.x,vTexCoordIn.y);
    vec4  color1    = texture2D (sTexture1, vTexCoord);
    vec4  color2    = texture2D (sTexture2, vTexCoord);

    vec3  col1_hsl1 = RGBtoHSL(color1.rgb);
    float col1_intensity = col1_hsl1.z;

    vec3 col_hsl2  = RGBtoHSL(color2.rgb);
    col_hsl2.z    += col1_intensity * sSelectedIntensity1;
    vec3 col_rgb2  = HSLtoRGB(col_hsl2.rgb);
    color2         = vec4(col_rgb2.rgb, color2.a);

    gl_FragColor = color2;
}

Another nice effect can be achieved by enlightening the areas where the intensity is above 0.8 and darken the areas where the light is below 0.8:

void main ()
{
    vec2  vTexCoord = vec2(vTexCoordIn.x,vTexCoordIn.y);
    vec4  color1    = texture2D (sTexture1, vTexCoord);
    vec4  color2    = texture2D (sTexture2, vTexCoord);

    vec3  col1_hsl1 = RGBtoHSL(color1.rgb);
    float col1_intensity = col1_hsl1.z;

    vec3 col_hsl2  = RGBtoHSL(color2.rgb);

    float constVal = 0.8;
    if (col1_intensity > constVal)
        col_hsl2.z += (col1_intensity-constVal)*sSelectedIntensity1/(1.0-constVal);
    else
        col_hsl2.z += (col1_intensity-constVal)*sSelectedIntensity1/constVal;

    vec3 col_rgb2  = HSLtoRGB(col_hsl2.rgb);
    color2         = vec4(col_rgb2.rgb, color2.a);

    gl_FragColor = color2;
}

There are a lot of possibilities, you've to choose the best function for your needs.


If you want to "dim" the image, then you've to manipulate the lightness of each pixel, dependent on an "inverse" factor or the lightness of the other image (* (1.0 - col1_hsl1.z)) if the slider is below 0.5:

void main ()
{
    vec2  vTexCoord = vec2(vTexCoordIn.x,vTexCoordIn.y);
    vec4  color1    = texture2D (sTexture1, vTexCoord);
    vec4  color2    = texture2D (sTexture2, vTexCoord);

    vec3  col1_hsl1 = RGBtoHSL(color1.rgb);
    float col1_intensity = col1_hsl1.z;

    vec3 col_hsl2  = RGBtoHSL(color2.rgb);

    if (sSelectedIntensity1 < 0.5)
        col_hsl2.z *= (1.0 - col1_intensity * (1.0-2.0*sSelectedIntensity1));
    else
        col_hsl2.z += col1_intensity * (2.0*sSelectedIntensity1-1.0);

    vec3 col_rgb2  = HSLtoRGB(col_hsl2.rgb);
    color2         = vec4(col_rgb2.rgb, color2.a);

    gl_FragColor = color2;
}
Rabbid76
  • 202,892
  • 27
  • 131
  • 174
  • tried with HSL. Can you please check images attached . 0.5 on slider give exact image. also lighting works fine on all slider value. but why that black area comes around it when changing slider value – H.NS Aug 23 '19 at 10:56
  • Still around black is there – H.NS Aug 23 '19 at 11:04
  • 1
    @H.NS Of course it is black. If the lightness is zero, then the fragment get black. Possibly you want something different like `col_hsl2.z += (col1_intensity-0.8)*sSelectedIntensity1*5.0;` – Rabbid76 Aug 23 '19 at 12:42
  • Can you please check images attached ? First image attached shows light effect of image 1 on image2.  Second image is what I want to get on image1 when changing slider value.  Means,  code can able to remove all light effect on image1 which is caused by image2 at some point of slider value.  Hope the question I asked is clear now. – H.NS Aug 26 '19 at 06:08
  • I want to dim (not enlighten) the image dependent on the "bright" parts of the other image. – H.NS Aug 27 '19 at 04:35
  • @H.NS If you just "dim" a part of the image, then you'll get black "holes". – Rabbid76 Aug 27 '19 at 04:40
  • so is it not possible to get an output as in the image? – H.NS Aug 27 '19 at 04:46
  • @H.NS I added another solution (last part of the answer). – Rabbid76 Aug 27 '19 at 05:05
  • Still black "holes" appears when slider value reaches to zero. light is dimming correctly – H.NS Aug 27 '19 at 05:17
  • @H.NS Possibly, but they should be "smooth". I've not further ideas. Possibly you can ask a magician. – Rabbid76 Aug 27 '19 at 05:24
  • Thank you for your tireless effort on this. – H.NS Aug 27 '19 at 05:33