YUV_420_888到RGB转换

时间:2016-11-30 10:13:11

标签: java image computer-vision rgb yuv

我正在使用camera2,在ImageReader中我有YUV_420_888格式。我环顾四周,发现了一些将其转换为RGB的公式。但我有一些颜色的问题。以下是将其转换为RGB的代码:

ByteBuffer buffer0 = image.getPlanes()[0].getBuffer();
byte[] Y1 = new byte[buffer0.remaining()];
buffer0.get(Y1);
ByteBuffer buffer1 = image.getPlanes()[1].getBuffer();
byte[] U1 = new byte[buffer1.remaining()];
buffer1.get(U1);
ByteBuffer buffer2 = image.getPlanes()[2].getBuffer();
byte[] V1 = new byte[buffer2.remaining()];
buffer2.get(V1);
int Width = image.getWidth();
int Heigh = image.getHeight();
byte[] ImageRGB = new byte[image.getHeight()*image.getWidth()*4];

for(int i = 0; i<Heigh-1; i++){
    for (int j = 0; j<Width; j++){
        int Y = Y1[i*Width+j]&0xFF;
        int U = U1[(i/2)*(Width/2)+j/2]&0xFF;
        int V = V1[(i/2)*(Width/2)+j/2]&0xFF;
        U = U-128;
        V = V-128;
        int R,G,B;
        R = (int)(Y + 1.140*V);
        G = (int)(Y - 0.395*U - 0.581*V);
        B = (int)(Y + 2.032*U);
        if (R>255) {
            R = 255;
        } else if (R<0) {
            R = 0;
        }
        if (G>255) {
            G = 255;
        } else if (G<0) {
            G = 0;
        }
        if (B>255) {
            R = 255;
        } else if (B<0) {
            B = 0;
        }
        ImageRGB[i*4*Width+j*4] = (byte)R;
        ImageRGB[i*4*Width+j*4+1] = (byte)G;
        ImageRGB[i*4*Width+j*4+2] = (byte)B;
        ImageRGB[i*4*Width+j*4+3] = -1;
    }
}

当我将相机指向某种颜色this时。知道为什么以及如何解决这个问题?

编辑: 这是我用于在SurfaceView上发布的代码,但我认为它是正确的

Bitmap bm = Bitmap.createBitmap(image.getWidth(), image.getHeight(), 

Bitmap.Config.ARGB_8888);
bm.copyPixelsFromBuffer(ByteBuffer.wrap(ImageRGB));
Bitmap scaled = Bitmap.createScaledBitmap(bm, surfaceView.getWidth(), surfaceView.getHeight(), true);
Canvas c;
c = surfaceHolder.lockCanvas();
c.drawBitmap(scaled, 0, 0, null);
surfaceHolder.unlockCanvasAndPost(c);
image.close();

3 个答案:

答案 0 :(得分:2)

这看起来不像正确的YUV-> RGB变换。来自相机设备的YUV_420_888的camera2 API颜色空间是JFIF YUV颜色空间(与JPEG文件中的内容相同)。遗憾的是,目前尚未明确记录这一点。

JFIF YUV-> RGB变换在JPEG JFIF specification中定义如下:

R = Y + 1.402 (Cr-128)
G = Y - 0.34414 (Cb-128) - 0.71414 (Cr-128)
B = Y + 1.772 (Cb-128)

所以试着开始吧。并且为了完全澄清,Cb = U,Cr = V。

答案 1 :(得分:0)

您的代码中存在错误

    if (B>255) {
        B = 255; //was R = 255;
    } else if (B<0) {
        B = 0;
    }

尝试使用两种变体

R = Y + 1.402 * V
G = Y - 0.34414 * U - 0.71414 * V
B = Y + 1.772 * U

Or from here

R = yValue + (1.370705 * V);
G = yValue - (0.698001 * V) - (0.337633 * U);
B = yValue + (1.732446 * U);

答案 2 :(得分:0)

U,V平面的尺寸为(x,y / 2),请尝试

int offset = (i/2)*Width + j;
int U = U1[offset]&0xFF;
int V = V1[offset+1]&0xFF;