繁体   English   中英

Android中的视频帧捕获

[英]Video frame capture in Android

我正在尝试实现一个Android应用,该应用每秒捕获大约1张图片,对每张图片执行一些处理,然后将输出发送到文件中进行存储。 我的第一遍尝试类似以下内容:

public class MainActivity extends Activity {

    ...
    Handler loopHandler = new Handler();
    Runnable loopRunnable = new Runnable() {

        @Override
        public void run() {
            Thread pictureThread = new Thread(pictureRunnable);
            pictureThread.start();
            loopHandler.postDelayed(this, 1000);
        }
    };

    Runnable pictureRunnable = new Runnable() {
        @Override
        public void run() {
            mCamera.takePicture(null, null, mPicture);
        }    
    };

    private PictureCallback mPicture = new PictureCallback() {
        @Override
        public void onPictureTaken(byte[] data, Camera camera) {
        ... My processing code ...
        }
    }

以这种方式拍摄约4张照片后,该应用程序冻结。 因此,我猜测这可能是一种过于幼稚的方法,但是希望您能对为什么这种方法不起作用有更深入的了解。

有什么方法可以在不直接参与视频的情况下完成此操作,还是我最终将不得不创建一些将帧从视频流中拉出来的方法?

您可以为此使用OpenCV。 它使您可以对从相机接收到的每一帧进行操作。 http://opencv.org/

最好的办法是对您的代码进行更深入的研究,并确切地了解导致应用程序冻结的原因。 也许与您发布的代码无关,但与图像的实际处理有关。

过去似乎对我更好的另一种方法是完全跳过PictureCallback 相反,您可以使用PreviewCallbackhttp://developer.android.com/reference/android/hardware/Camera.PreviewCallback.html )。 该回调在每个帧上触发,因此您可以简单地检查该帧内部是否自上次处理图像以来已超过1秒,如果是,则在另一个线程上进行图像处理。

我还没有测试过,但是像这样:

myCamera.setPreviewCallback(new PreviewCallback() {

    @Override
    public void onPreviewFrame(byte[] data, Camera camera) {

        // previousTime is defined as a member variable
        long timeElapsed = System.currentTimeMillis() - previousTime;

        if(timeElapsed > 1000) {

            // reset values for the next run
            previousTime = System.currentTimeMillis();

            // process the image (just an example, you should do this inside an AsyncTask)
            Size previewSize = myCamera.getParameters().getPreviewSize();
            ByteArrayOutputStream out = new ByteArrayOutputStream();
            YuvImage yuvImage = new YuvImage(data, myCamera.getParameters().getPreviewFormat(), previewSize.width,previewSize.height, null);
            yuvImage.compressToJpeg(new Rect(0, 0, previewSize.width, previewSize.height), 100, out);
            byte[] imageBytes = out.toByteArray();

            Options options = new Options();
            options.inSampleSize = 1;
            Bitmap image = BitmapFactory.decodeByteArray(imageBytes, 0, imageBytes.length, options);

            // you now have the image bitmap which you can use to apply your processing ...
        }

    }
});

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM