YUV到RGB转换由片段着色器 [英] YUV to RGB conversion by fragment shader

查看:841
本文介绍了YUV到RGB转换由片段着色器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个问题,从YUV格式为RGB Android摄像头preVIEW皈依。转换的目的是应用一些影响。我试图通过片段着色器来进行转换,因为皈依母语code是慢(约14fps)。这是我用过的参考 http://jyrom.tistory.com/m /后/查看/ ID / 187 。我尝试这个端口code到Android平台,但结果却是黑绿色的矩形。但是,我可以看一些形式,通过它我得到的输出。能否请你尽量帮我解决这个问题。我相信这是流行的问题:应用效果的相机preVIEW。我也给一个链接到我的项目进行测试: https://开头DL。 dropbox.com/u/12829395/application/FilterGL/FilterGL.zip 。 谢谢。
更新时间:
这是我的在previewFrame 方式:

 在previewFrame公共无效(byte []的数据,摄像头摄像头){
    yBuffer.put(数据);
    yBuffer.position(0);

    System.arraycopy(数据,U_INDEX,UDATA,0,LENGTH_4 * 2);
    uBuffer.put(UDATA);
    uBuffer.position(0);

    System.arraycopy(数据,V_INDEX,VDATA,0,LENGTH_4);
    vBuffer.put(VDATA);
    vBuffer.position(0);
}
 

这是我怎么绑定字节数组OpenGL的纹理 onDrawFrame 方式:

  GLES20.glUniform1i(yTexture,1);
    GLES20.glTexImage2D(GLES20.GL_TEXTURE_2D,0,GLES20.GL_LUMINANCE,
            320,240,0,GLES20.GL_LUMINANCE,GLES20.GL_UNSIGNED_BYTE,yBuffer);
    GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D,GLES20.GL_TEXTURE_MIN_FILTER,GLES20.GL_LINEAR);
    GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D,GLES20.GL_TEXTURE_MAG_FILTER,GLES20.GL_LINEAR);

    GLES20.glUniform1i(uTexture,2);
    GLES20.glTexImage2D(GLES20.GL_TEXTURE_2D,0,GLES20.GL_LUMINANCE,
            160,120,0,GLES20.GL_LUMINANCE,GLES20.GL_UNSIGNED_BYTE,uBuffer);
    GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D,GLES20.GL_TEXTURE_MIN_FILTER,GLES20.GL_LINEAR);
    GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D,GLES20.GL_TEXTURE_MAG_FILTER,GLES20.GL_LINEAR);

    GLES20.glUniform1i(vTexture,3);
    GLES20.glTexImage2D(GLES20.GL_TEXTURE_2D,0,GLES20.GL_LUMINANCE,
            160,120,0,GLES20.GL_LUMINANCE,GLES20.GL_UNSIGNED_BYTE,vBuffer);
    GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D,GLES20.GL_TEXTURE_MIN_FILTER,GLES20.GL_LINEAR);
    GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D,GLES20.GL_TEXTURE_MAG_FILTER,GLES20.GL_LINEAR);
 

这是我的片段着色器code:

的#ifdef GL_ES precision highp浮动; #ENDIF 不同VEC2 v_texCoord; 统一sampler2D y_texture; 统一sampler2D u_texture; 统一sampler2D v_texture; 无效的主要() {     浮NX,NY,R,G,B,Y,U,V;     NX = v_texCoord.x;     NY = v_texCoord.y;     Y =的Texture2D(y_texture,v_texCoord).R;     U =的Texture2D(u_texture,v_texCoord).R;     V =的Texture2D(v_texture,v_texCoord).R;     Y = 1.1643 *(Y-0.0625);     U = U-0.5;     V = -0.5;     R = Y + 1.5958 * V;     G = Y型0.39173 * U-0.81290 * V;     B = Y + 2.017 * U;     gl_FragColor = vec4(R,G,B,1.0); }

解决方案

不知道你是否已经解决了这个问题problem.My答案

  1. 在默认情况下相机输出为NV12,但在片段着色器YUV您使用YV12为RGB - > RGB。 你将不得不做 设置previewFormat(ImageFormat.YV12); ,或者可能使用一些其他的着色器
  2. 有3个纹理,你一定要做

    GLES20.glActiveTexture(GLES20.GL_TEXTURE2); GLES20.glBindTexture(GLES20.GL_TEXTURE_2D,muTextureName)

    调用任何glTexImage2D之前。和glTexSubImage2D

  3. 您也可以使用glTexSubImage2D每帧glTexImage2D一次。

  4. U和V的尺寸是一样的,ATLEAST为YV12,

    System.arraycopy(数据,U_INDEX,UDATA,0,LENGTH_4 * 2);

    应该是 System.arraycopy(数据,U_INDEX,UDATA,0,LENGTH_4);  相应地更改大小,在code。

I've a problem with convertion of camera preview in Android from YUV format to RGB. The purpose of conversion is to apply some effects. I try to convert by fragment shader because convertion by native code is slow (about 14fps). The reference which I've used is http://jyrom.tistory.com/m/post/view/id/187. I try to port this code to Android platform, but the result is black-green rectangles. But, I can watch some form through the output which I get. Could you please try to help me to resolve this issue. I believe this is popular problem: apply effects to camera preview. I also give a link to my project for testing: https://dl.dropbox.com/u/12829395/application/FilterGL/FilterGL.zip. Thank you.
UPDATED:
This is my onPreviewFrame method:

public void onPreviewFrame(byte[] data, Camera camera) {
    yBuffer.put(data);
    yBuffer.position(0);

    System.arraycopy(data, U_INDEX, uData, 0, LENGTH_4 * 2);
    uBuffer.put(uData);
    uBuffer.position(0);

    System.arraycopy(data, V_INDEX, vData, 0, LENGTH_4);
    vBuffer.put(vData);
    vBuffer.position(0);
}

This is how I bind byte arrays to OpenGL texture in onDrawFrame method:

    GLES20.glUniform1i(yTexture, 1);
    GLES20.glTexImage2D(   GLES20.GL_TEXTURE_2D, 0, GLES20.GL_LUMINANCE,
            320, 240, 0, GLES20.GL_LUMINANCE, GLES20.GL_UNSIGNED_BYTE, yBuffer);
    GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_LINEAR);
    GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_LINEAR);

    GLES20.glUniform1i(uTexture, 2);
    GLES20.glTexImage2D(   GLES20.GL_TEXTURE_2D, 0, GLES20.GL_LUMINANCE,
            160, 120, 0, GLES20.GL_LUMINANCE, GLES20.GL_UNSIGNED_BYTE, uBuffer);
    GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_LINEAR);
    GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_LINEAR);

    GLES20.glUniform1i(vTexture, 3);
    GLES20.glTexImage2D(   GLES20.GL_TEXTURE_2D, 0, GLES20.GL_LUMINANCE,
            160, 120, 0, GLES20.GL_LUMINANCE, GLES20.GL_UNSIGNED_BYTE, vBuffer);
    GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_LINEAR);
    GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_LINEAR);

And this is my fragment shader code:

#ifdef GL_ES
precision highp float;
#endif

varying vec2 v_texCoord;
uniform sampler2D y_texture;
uniform sampler2D u_texture;
uniform sampler2D v_texture;

void main()
{   
    float nx,ny,r,g,b,y,u,v;
    nx=v_texCoord.x;
    ny=v_texCoord.y;
    y=texture2D(y_texture,v_texCoord).r;
    u=texture2D(u_texture,v_texCoord).r;
    v=texture2D(v_texture,v_texCoord).r;

    y=1.1643*(y-0.0625);
    u=u-0.5;
    v=v-0.5;

    r=y+1.5958*v;
    g=y-0.39173*u-0.81290*v;
    b=y+2.017*u;

    gl_FragColor = vec4(r,g,b,1.0);
}

解决方案

Not sure if you have already fixed this problem.My answer

  1. By default Camera output is NV12, but in fragment shader YUV to RGB you are using YV12 -> RGB. You will have to do setPreviewFormat(ImageFormat.YV12);, or may be use some other shader
  2. There are 3 textures , make sure you do

    GLES20.glActiveTexture(GLES20.GL_TEXTURE2); GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, muTextureName)

    before call to any glTexImage2D. and glTexSubImage2D

  3. You can also use glTexSubImage2D with every frame and glTexImage2D once.

  4. size of U and V is same , atleast for YV12,

    System.arraycopy(data, U_INDEX, uData, 0, LENGTH_4 * 2);

    should be System.arraycopy(data, U_INDEX, uData, 0, LENGTH_4); change the size accordingly in the code.

这篇关于YUV到RGB转换由片段着色器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆