2016-05-31 13 views
4

Für Luminace Histogramm BerechnungLuminanz-Histogramm Berechnung in GPU-android OpenGL ES 3.0

Ich habe den Code aus dem Projekt GPU Bild ios von Brad Larson verwendet.

Er hat Blending für die Histogrammberechnung verwendet.

Anbringen des Vertex und Fragment-Shader

Vertexshader

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

Fragment-Shader

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

i eine 256x1-Textur mit einem FBO angebracht verwendet und als Eingabe in dem Pixelkarte zur Vertexshader Textur ist wie folgt definiert

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

Und mein onDrawFrame geht so

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

i wird mit 1 Pixel von 16 für Histogramm-Berechnung.

Jetzt bekomme ich die Grafik und die Werte. Aber wenn mit Matlab und andere Software wie irfanview verifiziert, scheint es abweichend.

Anbringen des Graphen in Excel erstellt values from my application

verified values using matlab

wird diese Änderung zu erwarten oder ich einige Fehler mache. Könnte jemand helfen, danke im voraus

+0

übersprungen Wo steht Ihr "60" kommt? Das macht es einmal alle 15 Pixel und nicht alle 16 Pixel. – 246tNt

+0

Außerdem würde ich vorschlagen, 0,5 hinzuzufügen, um sicherzustellen, dass Sie den GL_POINT in der Mitte des Pixels zeichnen. Außerdem sollte die Konstante 1/256.0 und nicht 1/255.0 sein. 'gl_Position = vec4 (-1.0 + (0.5 + Luminanz) * (1.0/256.0), 0.5, 0.0, 1.0);' – 246tNt

+0

@ 246tNt Danke für den Vorschlag, aber auch nach der Verwendung von gl_Position = vec4 (-1.0 + (0.5 + Luminanz) * (1,0/256,0), 0,5, 0,0, 1,0); Ich bekomme Variation im Vergleich mit der Berechnung in Matlab –

Antwort

2

I C und Desktop-GL bin mit, aber hier ist der Kern von ihm:

Vertex-Shader

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

Fragment-Shader

#version 330 
out vec4 outputColor; 
void main() 
{ 
    outputColor = vec4(1.0, 1.0, 1.0, 1.0); 
} 

Init:

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

Zeichnung:

/* 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); 

Für brievety ich nur für den resultierenden Puffer des Init-Code setzen, alle VBO/VAO init/Bindung wurde

+0

kann ich glTexStorage2D verwenden (GL_TEXTURE_2D, 1, GL_R32F, 256, 1); In OpenGLES 3.0 habe ich glTeximage2d.Also verwendet, um das Ergebnis mit glreadpixel zu überprüfen –

+0

Scheint zu existieren: https://developer.android.com/reference/android/opengl/GLES30.html#glTexStorage2D%28int,%20int, % 20int,% 20int,% 20int% 29. Wie beim Readback: 'glReadPixels (0, 0, 256, 1, GL_RED, GL_FLOAT, buffer) sollte funktionieren. – 246tNt

+0

Ich habe überprüft, dass mein Gerät GL_EXT_COLOR_BUFFER_FLOAT unterstützt. also gerade jetzt ist mein Code GLES30.glTexImage2D (GLES30.GL_TEXTURE_2D, 0, GLES30.GL_RGBA32F, 256, 1, 0, GLES30.GL_RGBA, GLES30.GL_FLOAT, null); und der entsprechende glreadpixel ist GLES30.glReadPixels (0, 0, 256, 1, GLES30.GL_RGBA, GLES30.GL_FLOAT, PixelBufferTest); where PixelBufferTest ist ByteBuffer PixelBufferTest = ByteBuffer.allocateDirect (16 * 256 * 1); aber immer noch nicht funktioniert. Irgendeine Idee? –