Android Camera2:从相机预览中获取帧

时间:2018-02-09 13:26:20

标签: java android android-camera2

我是Android的初学者,我必须创建一个应用程序,使用Camera2实时绘制以RGB格式处理的相机图像。 我已经创建了一个活动,我根据谷歌示例为Camera2绘制数据和片段。好吧,关于相机的部分工作,但我有ImageReader处理帧的问题。在openCamera中,我为Image Reader打开了一个监听器,我试图创建一个后台线程来获取帧数据。

 private void openCamera(int width, int height) {
    // another part of code


        ImageReader.OnImageAvailableListener mOnImageAvailableListener = new ImageReader.OnImageAvailableListener() {
            @Override
            public void onImageAvailable(ImageReader reader) {
                Thread mythread = new Thread(new Runnable() {

                   @Override
                    public void run(){
                                        readImage = mImageReader.acquireLatestImage();
                                        if (readImage == null){
                                            Log.e(TAG, "ERROR");
                                        }

                                        float[] val = caricadato(readImage);
                                try {

                                    Thread.sleep(100);        //600
                                } catch (InterruptedException e) {
                                    //manage error...

                                }

                            }
                });
                mythread.start();}
};
mImageReader = ImageReader.newInstance(176, 144,
                35, 1);
mImageReader.setOnImageAvailableListener(mOnImageAvailableListener, mBackgroundHandler);
//....continue
}

“carica dato”方法提取绿色通道并使其成为平均值(要绘制的数据)。

 private float[] caricadato(Image image){
    Log.i(TAG, "The onImageAvailable thread id: " + Thread.currentThread().getId());
    float[] v = yuv2rgb(image);
    float media = valore_medio(v);
    dati_realtime[count]= media;
    Log.i(TAG,"dato media"+ media);
    Log.i(TAG,"dato real time "+ dati_realtime[count]);
    Log.i(TAG,"VALORE CONTATORE "+count);
    count++;
    image.close();
    return dati_realtime;
}

private float[] yuv2rgb(Image image){
    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 Height = image.getHeight();
    float[]verdi = new float[image.getHeight()*image.getWidth()];
    int contatore = 0;
    for(int i = 0; i<Height-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;
            float R,G,B;
            R = (float)(Y + 1.402 * V);
            G = (float)(Y - 0.34414 * U - 0.71414 * V);
            B = (float) (Y + 1.772 * U);
            verdi[contatore]= (byte)G;
            contatore++;
            }
    }
    return  verdi;
}

启动和恢复时的错误通常是:

 E/AndroidRuntime: FATAL EXCEPTION: Thread-5  Process: com.example.francesca.beatandgo, PID: 22610
                                                                             java.lang.IllegalStateException: maxImages (1) has already been acquired, call #close before acquiring more.
                                                                                 at android.media.ImageReader.acquireNextImage(ImageReader.java:398)
                                                                                 at android.media.ImageReader.acquireLatestImage(ImageReader.java:283)
                                                                                 at com.example.francesca.beatandgo.camera.Camera2VideoFragment$3$1.run(Camera2VideoFragment.java:506)
                                                                                 at java.lang.Thread.run(Thread.java:776)

Camera2VideoFragment.java:506在openCamera中为readImage = mImageReader.acquireLatestImage();

如何解决此问题?如何将数据传递给mainThread进入Activity?

0 个答案:

没有答案