我有两个图像。我必须找到强度大于0.8的第一张图像的点。同时,我必须在同一点上找到第二张图像的强度,并需要使用阈值/滑块值(范围从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);
}
实际上,如果image1和image2是分别来自两个辅助摄像机cam1和cam2的帧。如果将闪光灯放在cam1的前面,我应该能够调暗/消除相机2的帧上的这种灯光效果。
最佳答案
如果要修改颜色的亮度,则必须乘以[0,2]范围内的值而不是[0,1]范围内的值。如果乘以[0,1]范围内的值,则结果最多将与源一样明亮:
col_hsv.z *= sSelectedIntensity1 * 2.0;
如果要根据另一个图像的“亮”部分来启发图像,则必须在亮度上添加一个术语,该术语取决于(另一个图像的)亮度和滑块。例如。:
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;
}
有很多可能性,您必须根据需要选择最佳功能。
如果要“暗淡”图像,则必须根据“反”因子或如果滑块低于0.5,则取决于另一个图像(
* (1.0 - col1_hsl1.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;
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/