在Camera API 2中使用ImageReader捕获YUV_420_888格式的图像帧在双摄像头设备中无法提供正确的结果

时间:2019-01-02 13:33:23

标签: android android-camera2

我正在开发一个Android应用,该应用从相机预览中获取YUV_420_888格式的图像输入并将其转换为RGB等价物。这是一种心跳测量应用程序,当用户触摸相机表面时,它会从用户的指尖获取红色框。使用Camera API 2完成相机的实现,并使用ImageReader捕获图像帧,其格式设置为YUV_420_888。

imageReader = ImageReader.newInstance(smallest.getWidth(), smallest.getHeight(), ImageFormat.YUV_420_888, 1);

然后使用以下功能将YUV_420_888格式捕获的图像帧转换为RGB:

public static double[] decodeYUV420SP_888toRedBlueGreenAvg(byte[] Y1, byte[] U1, byte[] V1, int width, int height) {


    int Width = width;
    int Height = height;
    byte[] ImageRGB = new byte[Width*Height*4];

    double[] rgb =new double[3];
    for(int i = 0; i<Height-1; i++){
        for (int j = 0; j<Width; j++){
            int Y = Y1[i*Width+j]&0xFF -16;
            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.402*(V-128));
            G = (int) (Y - 0.34414 *(U-128) - 0.71414 *(V-128));
            B = (int) (Y + 1.772 *(U-128));*/

           //correct values
            R = (int)(Y + 1.140*V);
            G = (int)(Y - 0.395*U - 0.581*V);
            B = (int)(Y + 2.032*U);



            /*int y1192 = 1192 * Y;
            R = (y1192 + 1634 * V);
            G = (y1192 - 833 * V - 400 * U);
            B = (y1192 + 2066 * U);*/


          /*  Y_temp = 4768 * (Y - 16);
            R = (Y_temp + 6537 * (V - 128)) >> 12;
            G = (Y_temp - 3330 * (V - 128) - 1602 * (U - 128)) >> 12;
            B = (Y_temp + 8266 * (U - 128)) >> 12;*/

          //test
            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;
            rgb[0] = R;
            rgb[1] = G;
            rgb[2] = B;
        }
    }


    return rgb;}

图像保护程序类如下:

 private class ImageSaver implements Runnable {

    byte[] y1, u1, v1;
    int width, height;

    public ImageSaver(byte[] y1, byte[] u1, byte[] v1, int width, int height) {
        this.y1 = y1;
        this.u1 = u1;
        this.v1 = v1;
        this.width = width;
        this.height = height;
    }

    @Override
    public void run() {
        //if data or size == null ****


        if (y1 == null)
            throw new NullPointerException();


        if (textureView == null) throw new NullPointerException();

        current value == the expected value.
        if (!processing.compareAndSet(false, true)) return;


        //put width + height of the camera inside the variables
        int width = textureView.getWidth();
        int height = textureView.getHeight();
        RGBAvg = YUVtoRGB.decodeYUV420SP_888toRedBlueGreenAvg(y1, u1, v1, width, height);

然后使用rgb值进行一些处理。 这对于单摄像头设备工作正常,但对于双摄像头设备,rgb值以绿色而不是红色显示。特别是在Oppo和少数Redmi设备中,例如Oppo F9 pro和Redmi 6 pro。

任何帮助将不胜感激!

0 个答案:

没有答案