c# - 通过比较另一个图像的强度来改变图像的强度 - OpenTK

标签 c# image-processing glsl fragment-shader opentk

我有两张图片。我必须找到第一张图像中强度大于 0.8 的点。同时,我必须在相同点上找到第二张图像的强度,并且需要使用阈值/ slider 值(范围从 0 到 1)调整相同点上第二张图像上的光线。我做了如下。点上的黑色或深色区域的强度大于 0.8。 我正在尝试使用 HSV 的 z 值。
但是我应该能够调整 image2 上的光线,而不是这个黑色区域。我怎样才能做到这一点?

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

实际上,如果 image1 和 image2 分别是来自两个相邻相机 cam1 和 cam2 的帧。如果我在摄像头 1 前面放一个闪光灯,我应该能够调暗/消除摄像头 2 帧上的这种灯光效果。

最佳答案

如果您想修改颜色的亮度,您必须乘以 [0, 2] 范围内的值而不是 [0, 1] 范围内的值。如果您乘以 [0, 1] 范围内的值,结果将最多与源一样亮:

col_hsv.z *= sSelectedIntensity1 * 2.0;

如果您想根据另一幅图像的“明亮”部分来照亮图像,那么您必须为亮度添加一个术语,这取决于(另一幅图像的)亮度和 slider 。例如:

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

如果你想改变亮度,我建议使用 HSL (hue, saturation, lightness)颜色范围而不是 HSV (hue, saturation, value .
与 HSV 相比,在 HSL 中,第三个值表示颜色的亮度:

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;
}

像这样使用函数:

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;
}

另一种选择是根据其他图像的亮度修改整个图像的亮度。在这种情况下,不需要系数 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;
}

另一个很好的效果可以通过照亮强度高于 0.8 的区域并使光线低于 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;
}

有很多可能性,您必须选择最适合您需要的功能。


如果您想“调暗”图像,则必须根据“逆”因子或其他图像的亮度来操纵每个像素的亮度 (* (1.0 - col1_hsl1.z )) 如果 slider 低于 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;
}

关于c# - 通过比较另一个图像的强度来改变图像的强度 - OpenTK,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57622908/

相关文章:

c# - Identity 3 MVC 6 中的授权策略

opengl-es - GLSL 片段着色器中的动态工作量

javascript - 如何使用 Three.js 在着色器中传递和使用查找表

C# - 在 USB FAST 上创建大文件

c# - setter 上的“System.StackOverflowException”

c++ - Opencv Mat内存管理

python - 如何提高这种numpy迭代的效率?

python - 具有多维(或非标量)输出的 Scipy 过滤器

opengl - 为什么 GL_MAX_ARRAY_TEXTURE_LAYERS 比 GL_MAX_TEXTURE_SIZE 小很多?

c# - 使用列名称的字符串列表查询 SQL 表