问题
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);
}
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.
回答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;
}
来源:https://stackoverflow.com/questions/57622908/change-the-intensity-of-an-image-by-comparing-intensity-of-another-image-opent