如何在Android中从相机流中获取帧?

时间:2014-04-18 10:16:35

标签: android video camera video-processing hsv

我正在为Android开发一种研究应用程序。 我正在进行的子任务是从Camera的实时视频流中获取一个帧。 我试图从SurfaceView源获取它(并解码YUV - > RGB - > HSV),但FPS太低(约5-7 FPS)。

所以,请告诉我,如何直接从相机视频流中获取视频帧(某些低级内容,如onFrameChanged())

我是怎么做到的:

 @Override
    public void onPreviewFrame(byte[] data, Camera camera) {
        yuvs.add(data);
        rgbText.setText("FRAMES: " + count);
        count++;
    }

其中yuvs是

 private ArrayList<byte[]> yuvs;

感谢任何安装或代码段

3 个答案:

答案 0 :(得分:1)

实际上,FPS对光照条件非常敏感,它可以在很大范围内变化(在我的测试中为8-30)。我不知道有任何可靠的方法来提高预览的FPS,但只有诸如降低分辨率,使用本机API等建议。我可以建议使用这个lib https://github.com/natario1/CameraView-它提供与本机API相同的FPS,但会大大减少代码量。

以下是获取RGB位图的示例(科特琳):

cameraView.addFrameProcessor { frame ->
        if(frame!=null) {
            val data = frame.data
            val size = frame.size
            // Process...
            // cameraView.previewSize

            val yuvImage = YuvImage(data, ImageFormat.NV21, size.width, size.height, null)
            val os = ByteArrayOutputStream()
            yuvImage.compressToJpeg(Rect(0, 0, size.width, size.height), 100, os)
            val jpegByteArray = os.toByteArray()
            var bitmap = BitmapFactory.decodeByteArray(jpegByteArray, 0, jpegByteArray.size)
        }
}

借助openCV,您可以将其快速转换为HSV:

val bmp = convert(bitmap, Bitmap.Config.ARGB_8888)
var mat = Mat(bmp.width, bmp.height, CvType.CV_8UC4)
Utils.bitmapToMat(bmp, mat)
Imgproc.cvtColor(mat, mat, Imgproc.COLOR_RGB2HSV)

fun convert(bitmap: Bitmap, config: Bitmap.Config): Bitmap {
        val convertedBitmap = Bitmap.createBitmap(bitmap.width, bitmap.height, config)
        val canvas = Canvas(convertedBitmap)
        val paint = Paint()
        paint.color = Color.BLACK
        canvas.drawBitmap(bitmap, 0F, 0F, paint)
        return convertedBitmap
    }

答案 1 :(得分:0)

在Camera对象上设置

setPreviewCallback(Camera.PreviewCallback cb)

Camera.PreviewCallback

倍率

onPreviewFrame(byte[] data, Camera camera)

答案 2 :(得分:0)

ArrayList是在游戏,帧渲染等中使用最差的类。试试这个而不是 public void onPreviewFrame(byte[] data, Camera camera) { yuvs[count] = data; rgbText.setText("FRAMES: " + count); count++; }
并将ArrayList<byte[]>替换为byte[][]