Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/221.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 使用onPreviewFrame运行ML模型_Java_Android_Android Camera - Fatal编程技术网

Java 使用onPreviewFrame运行ML模型

Java 使用onPreviewFrame运行ML模型,java,android,android-camera,Java,Android,Android Camera,因此,我正在使用遗留的CameraAPI(据我所知)获取previewFrame回调,然后运行一些我拥有的机器学习模型。我已经确认,当我通过onPictureTaken回调拍摄图片时,如果给我解码的位图,机器学习模型可以工作。现在在下面的示例中,我只是简单地在ML Kit的条形码扫描器上进行测试,作为一个基本情况,但是我的自定义模型似乎也可以与onPictureTaken回调一起工作 从我收集的资料来看,使用onPreviewFrame不一定是最好的方法,但为了快速体验(和学习经验),我决定走这

因此,我正在使用遗留的CameraAPI(据我所知)获取previewFrame回调,然后运行一些我拥有的机器学习模型。我已经确认,当我通过onPictureTaken回调拍摄图片时,如果给我解码的位图,机器学习模型可以工作。现在在下面的示例中,我只是简单地在ML Kit的条形码扫描器上进行测试,作为一个基本情况,但是我的自定义模型似乎也可以与onPictureTaken回调一起工作

从我收集的资料来看,使用onPreviewFrame不一定是最好的方法,但为了快速体验(和学习经验),我决定走这条路。基于我从其他在线解决方案中尝试的一切,我似乎无法让任何东西正常工作。下面的代码返回null:

@Override
public void onPreviewFrame(byte[] data, Camera camera) {
//        Log.d("onPreviewFrame bytes.length", String.valueOf(bytes.length));
//        final Bitmap bmp = BitmapFactory.decodeByteArray(bytes, 0, bytes.length);
//        Log.d("onPreviewFrame bmp.getHeight()", String.valueOf(bmp.getHeight()));

    Camera.Parameters parameters = camera.getParameters();
    int width = parameters.getPreviewSize().width;
    int height = parameters.getPreviewSize().height;


    Log.d("onPreviewFrame - width", String.valueOf(width));
    Log.d("onPreviewFrame - height", String.valueOf(height));
    Log.d("onPreviewFrame - parameters.getPreviewFormat()", String.valueOf(parameters.getPreviewFormat()));

    YuvImage yuv = new YuvImage(data, parameters.getPreviewFormat(), width, height, null);

    ByteArrayOutputStream out = new ByteArrayOutputStream();
    yuv.compressToJpeg(new Rect(0, 0, width, height), 100, out);

//
//        byte[] bytes = out.toByteArray();
//        final Bitmap bitmap = BitmapFactory.decodeByteArray(bytes, 0, bytes.length);


    byte[] bytes = yuv.getYuvData();
    final Bitmap bitmap = BitmapFactory.decodeByteArray(bytes, 0, bytes.length);

    extractBarcode(FirebaseVisionImage.fromBitmap(bitmap), bitmap);
}
以下是我尝试过的其他方法:

@Override
public void onPreviewFrame(byte[] data, Camera camera) {
//        Log.d("onPreviewFrame bytes.length", String.valueOf(bytes.length));
//        final Bitmap bmp = BitmapFactory.decodeByteArray(bytes, 0, bytes.length);
//        Log.d("onPreviewFrame bmp.getHeight()", String.valueOf(bmp.getHeight()));

    Camera.Parameters parameters = camera.getParameters();
    int width = parameters.getPreviewSize().width;
    int height = parameters.getPreviewSize().height;


    Log.d("onPreviewFrame - width", String.valueOf(width));
    Log.d("onPreviewFrame - height", String.valueOf(height));

    YuvImage yuv = new YuvImage(data, parameters.getPreviewFormat(), width, height, null);

    ByteArrayOutputStream out = new ByteArrayOutputStream();
    yuv.compressToJpeg(new Rect(0, 0, width, height), 100, out);


    byte[] bytes = out.toByteArray();
    final Bitmap bitmap = BitmapFactory.decodeByteArray(bytes, 0, bytes.length);

    extractBarcode(FirebaseVisionImage.fromBitmap(bitmap), bitmap);
}
不幸的是,我得到了这个错误:

ML工具包检测到您似乎将相机帧作为位图对象传递给检测器。这是低效的。请为camera2 API使用YUV_420_888格式,或为(传统)camera API使用NV21格式,并直接将字节数组传递给ML工具包

参数为。getPreviewFormat()返回17,即NV21。我还尝试将其更改为ImageFormat.YUV_420_888,但这导致了以下非法参数异常:

目前仅支持ImageFormat.NV21和ImageFormat.YUY2


不要使用Camera API,请尝试使用。它很容易使用,只要从相机接收到帧,您就可以执行代码。在尝试将ML模型与相机集成时,我遇到了类似的错误,然后转向CameraX

基本上,我们将创建一个
ImageAnalysis.analyzer
类,通过它我们将获得
Image
对象(帧)。使用扩展函数,我们将此
图像
对象转换为
YuvImage

可以按照此操作使用CameraX分析帧。您将创建一个扩展
ImageAnalysis.Analyzer
类的类

class FrameAnalyser() : ImageAnalysis.Analyzer {

    override fun analyze(image: ImageProxy?, rotationDegrees: Int) {
        val yuvImage = image?.image?.toYuv() // The extension function
    }
}
创建将
图像
转换为
YuvImage
的扩展函数

private fun Image.toYuv(): YuvImage {
    val yBuffer = planes[0].buffer
    val uBuffer = planes[1].buffer
    val vBuffer = planes[2].buffer
    val ySize = yBuffer.remaining()
    val uSize = uBuffer.remaining()
    val vSize = vBuffer.remaining()
    val nv21 = ByteArray(ySize + uSize + vSize)
    yBuffer.get(nv21, 0, ySize)
    vBuffer.get(nv21, ySize, vSize)
    uBuffer.get(nv21, ySize + vSize, uSize)
    val yuvImage = YuvImage(nv21, ImageFormat.NV21, this.width, this.height, null)
    return yuvImage
}

您可以根据需要更改YUV图像格式。参考这些。

而不是直接通过FirebaseVisionImage

extractBarcode(FirebaseVisionImage.fromBitmap(bitmap), bitmap);
你可以这样做

var bitmap = toARGBBitmap(ocrBitmap)
  extractBarcode(FirebaseVisionImage.fromBitmap(bitmap), bitmap);

 private fun toARGBBitmap(img: Bitmap): Bitmap {
        return img.copy(Bitmap.Config.ARGB_8888, true)
    }

你可以试试这个:)

有趣。给我几个小时让这一切开始,我会让你知道会发生什么。谢谢Shubham:几个小时过去了,几天过去了(其他事情也发生了)。所以我还是遇到了同样的问题。所以现在为了可视化,我也将帧保存到本地存储器中,图像全部失真。此外,ML Kit警告仍在发生。在分析时,我执行imageproxy.getImage,然后将其转换为位图(使用NV21格式),然后在本地保存,并使用ML工具包提取条形码。但奇怪的是,ML Kit的OCR似乎与图像运行得非常好。。。。。