GPU中的亮度直方图计算-android opengl es 3.0
Luminance histogram calculation in GPU-android opengl es 3.0
用于亮度直方图计算
我使用了 Brad Larson 的项目 GPU 图像 ios 中的代码。
他使用混合来计算直方图。
附加顶点和片段着色器
顶点着色器
#version 300 es
in vec4 position;
out vec3 colorFactor;
const vec3 W = vec3(0.299, 0.587, 0.114);
void main()
{
float luminance = dot(position.xyz, W);
colorFactor = vec3(1.0, 1.0, 1.0);
gl_Position = vec4(-1.0 + (luminance * 0.00784313725), 0.0, 0.0, 1.0);
gl_PointSize = 1.0;
} ;
片段着色器
#version 300 es
const lowp float scalingFactor = 1.0 / 256.0;
in lowp vec3 colorFactor;
out vec4 gl_FragColor;\n"+
void main()
{
gl_FragColor = vec4(colorFactor * scalingFactor , 1.0);
};
我使用了附加到 FBO 的 256x1 纹理并将像素作为输入传递给顶点着色器。
纹理定义如下
GLES30.glTexParameterf(GLES30.GL_TEXTURE_2D, GLES30.GL_TEXTURE_WRAP_S, GLES30.GL_CLAMP_TO_EDGE);
GLES30.glTexParameterf(GLES30.GL_TEXTURE_2D, GLES30.GL_TEXTURE_WRAP_T, GLES30.GL_CLAMP_TO_EDGE);
GLES30.glTexParameterf(GLES30.GL_TEXTURE_2D, GLES30.GL_TEXTURE_MIN_FILTER, GLES30.GL_NEAREST);
GLES30.glTexParameterf(GLES30.GL_TEXTURE_2D, GLES30.GL_TEXTURE_MAG_FILTER, GLES30.GL_LINEAR);
GLES30.glTexImage2D(GLES30.GL_TEXTURE_2D, 0, GLES30.GL_RGBA,
256, 1, 0, GLES30.GL_RGBA,
GLES30.GL_UNSIGNED_BYTE, null);
我的 onDrawFrame 是这样的
GLES30.glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
GLES30.glClear(GLES30.GL_COLOR_BUFFER_BIT);
GLES30.glBlendEquation(GLES30.GL_FUNC_ADD);
GLES30.glBlendFunc(GLES30.GL_ONE, GLES30.GL_ONE);
GLES30.glEnable(GLES30.GL_BLEND);
filterPositionAttribute = mshader2.getHandle("position");
GLES30.glVertexAttribPointer(filterPositionAttribute, 4, GLES30.GL_UNSIGNED_BYTE,false,60, PixelBuffer);
GLES30.glEnableVertexAttribArray(filterPositionAttribute);
GLES30.glDrawArrays(GLES30.GL_POINTS, 0, mViewportWidth * mViewportHeight /16);
我将使用 16 个像素中的 1 个来计算直方图。
现在我正在获取图表和值。
但是用matlab和irfanview等其他软件验证时,出现偏差
附上在excel中创建的图表
values from my application
这种变化是预期的还是我犯了一些错误。
任何人都可以帮助,在此先感谢
我正在使用 C 和桌面 GL,但这是它的要点:
顶点着色器
#version 330
layout (location = 0) in vec2 inPosition;
void main()
{
int x = compute the bin (0 to 255) from inPosition;
gl_Position = vec4(
-1.0 + ((x + 0.5) / 128.0),
0.5,
0.0,
1.0
);
}
片段着色器
#version 330
out vec4 outputColor;
void main()
{
outputColor = vec4(1.0, 1.0, 1.0, 1.0);
}
初始化:
glGenTextures(1, &tex);
glGenFramebuffers(1, &fbo);
glActiveTexture(GL_TEXTURE0);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexStorage2D(GL_TEXTURE_2D, 1, GL_R32F, 256, 1);
glBindFramebuffer(GL_FRAMEBUFFER, fbo);
glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, tex, 0);
绘图:
/* Upload data */
glBufferData(GL_ARRAY_BUFFER, num_input_data * 2 * sizeof(float), input_data_ptr, GL_STREAM_DRAW);
/* Clear buffer */
const float zero[4] = { 0.0f, 0.0f, 0.0f, 0.0f };
glClearBufferfv(GL_COLOR, 0, zero);
/* Init viewport */
glViewport(0, 0, 256, 1);
/* Draw */
glDrawArrays(GL_POINTS, 0, num_input_data);
为简洁起见,我只放置了结果缓冲区的初始化代码,所有 VBO/VAO init/binding 都被跳过了
用于亮度直方图计算
我使用了 Brad Larson 的项目 GPU 图像 ios 中的代码。
他使用混合来计算直方图。
附加顶点和片段着色器
顶点着色器
#version 300 es
in vec4 position;
out vec3 colorFactor;
const vec3 W = vec3(0.299, 0.587, 0.114);
void main()
{
float luminance = dot(position.xyz, W);
colorFactor = vec3(1.0, 1.0, 1.0);
gl_Position = vec4(-1.0 + (luminance * 0.00784313725), 0.0, 0.0, 1.0);
gl_PointSize = 1.0;
} ;
片段着色器
#version 300 es
const lowp float scalingFactor = 1.0 / 256.0;
in lowp vec3 colorFactor;
out vec4 gl_FragColor;\n"+
void main()
{
gl_FragColor = vec4(colorFactor * scalingFactor , 1.0);
};
我使用了附加到 FBO 的 256x1 纹理并将像素作为输入传递给顶点着色器。 纹理定义如下
GLES30.glTexParameterf(GLES30.GL_TEXTURE_2D, GLES30.GL_TEXTURE_WRAP_S, GLES30.GL_CLAMP_TO_EDGE);
GLES30.glTexParameterf(GLES30.GL_TEXTURE_2D, GLES30.GL_TEXTURE_WRAP_T, GLES30.GL_CLAMP_TO_EDGE);
GLES30.glTexParameterf(GLES30.GL_TEXTURE_2D, GLES30.GL_TEXTURE_MIN_FILTER, GLES30.GL_NEAREST);
GLES30.glTexParameterf(GLES30.GL_TEXTURE_2D, GLES30.GL_TEXTURE_MAG_FILTER, GLES30.GL_LINEAR);
GLES30.glTexImage2D(GLES30.GL_TEXTURE_2D, 0, GLES30.GL_RGBA,
256, 1, 0, GLES30.GL_RGBA,
GLES30.GL_UNSIGNED_BYTE, null);
我的 onDrawFrame 是这样的
GLES30.glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
GLES30.glClear(GLES30.GL_COLOR_BUFFER_BIT);
GLES30.glBlendEquation(GLES30.GL_FUNC_ADD);
GLES30.glBlendFunc(GLES30.GL_ONE, GLES30.GL_ONE);
GLES30.glEnable(GLES30.GL_BLEND);
filterPositionAttribute = mshader2.getHandle("position");
GLES30.glVertexAttribPointer(filterPositionAttribute, 4, GLES30.GL_UNSIGNED_BYTE,false,60, PixelBuffer);
GLES30.glEnableVertexAttribArray(filterPositionAttribute);
GLES30.glDrawArrays(GLES30.GL_POINTS, 0, mViewportWidth * mViewportHeight /16);
我将使用 16 个像素中的 1 个来计算直方图。
现在我正在获取图表和值。 但是用matlab和irfanview等其他软件验证时,出现偏差
附上在excel中创建的图表 values from my application
这种变化是预期的还是我犯了一些错误。 任何人都可以帮助,在此先感谢
我正在使用 C 和桌面 GL,但这是它的要点:
顶点着色器
#version 330
layout (location = 0) in vec2 inPosition;
void main()
{
int x = compute the bin (0 to 255) from inPosition;
gl_Position = vec4(
-1.0 + ((x + 0.5) / 128.0),
0.5,
0.0,
1.0
);
}
片段着色器
#version 330
out vec4 outputColor;
void main()
{
outputColor = vec4(1.0, 1.0, 1.0, 1.0);
}
初始化:
glGenTextures(1, &tex);
glGenFramebuffers(1, &fbo);
glActiveTexture(GL_TEXTURE0);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexStorage2D(GL_TEXTURE_2D, 1, GL_R32F, 256, 1);
glBindFramebuffer(GL_FRAMEBUFFER, fbo);
glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, tex, 0);
绘图:
/* Upload data */
glBufferData(GL_ARRAY_BUFFER, num_input_data * 2 * sizeof(float), input_data_ptr, GL_STREAM_DRAW);
/* Clear buffer */
const float zero[4] = { 0.0f, 0.0f, 0.0f, 0.0f };
glClearBufferfv(GL_COLOR, 0, zero);
/* Init viewport */
glViewport(0, 0, 256, 1);
/* Draw */
glDrawArrays(GL_POINTS, 0, num_input_data);
为简洁起见,我只放置了结果缓冲区的初始化代码,所有 VBO/VAO init/binding 都被跳过了