首页 > 解决方案 > Flutter - 尝试使用 Tensorflowlite - FloatEfficientNet

问题描述

我正在尝试使用在本机 swift 和 android/java 中成功推断的模型在颤振中做同样的事情,特别是它的 android 方面。

在这种情况下,我收到的值很遥远。

到目前为止我做了什么:

  1. 我采用了 tensorflowlite android 示例 github 存储库:https ://github.com/tensorflow/examples/tree/master/lite/examples/image_classification/android ,发现 FloatEfficientNet 选项准确地为我的模型提供了值。

  2. 我使用了 flutter_tflite 库,并对其进行了修改,以便 android 代码的推理部分与上面的 tensorflow 示例相匹配: https ://github.com/shaqian/flutter_tflite

  3. 我使用了本教程并包含了使用上述库通过平台通道推断 tensorflow 的 repo: https ://github.com/flutter-devs/tensorflow_lite_flutter

通过颤振教程,我使用了相机插件,它可以从相机的实时源中流式传输 CameraImage 对象。我将它传递到修改后的颤振张量流库中,该库使用平台通道将图像传递到 android 层。它是作为字节数组列表执行的。(3 个平面,YuvImage)。带有工作 floatefficientnet 代码的 tensorflow android 示例(1),示例位图。所以我使用这种方法来转换:

    public Bitmap imageToBitmap(List<byte[]> planes, float rotationDegrees, int width, int height) {

        // NV21 is a plane of 8 bit Y values followed by interleaved  Cb Cr
        ByteBuffer ib = ByteBuffer.allocate(width * height * 2);

        ByteBuffer y = ByteBuffer.wrap(planes.get(0));
        ByteBuffer cr = ByteBuffer.wrap(planes.get(1));
        ByteBuffer cb = ByteBuffer.wrap(planes.get(2));
        ib.put(y);
        ib.put(cb);
        ib.put(cr);

        YuvImage yuvImage = new YuvImage(ib.array(),
                ImageFormat.NV21, width, height, null);

        ByteArrayOutputStream out = new ByteArrayOutputStream();
        yuvImage.compressToJpeg(new Rect(0, 0, width, height), 50, out);
        byte[] imageBytes = out.toByteArray();
        Bitmap bm = BitmapFactory.decodeByteArray(imageBytes, 0, imageBytes.length);
        Bitmap bitmap = bm;

        // On android the camera rotation and the screen rotation
        // are off by 90 degrees, so if you are capturing an image
        // in "portrait" orientation, you'll need to rotate the image.
        if (rotationDegrees != 0) {
            Matrix matrix = new Matrix();
            matrix.postRotate(rotationDegrees);
            Bitmap scaledBitmap = Bitmap.createScaledBitmap(bm,
                    bm.getWidth(), bm.getHeight(), true);
            bitmap = Bitmap.createBitmap(scaledBitmap, 0, 0,
                    scaledBitmap.getWidth(), scaledBitmap.getHeight(), matrix, true);
        }
        return bitmap;
    }

推理成功,我能够将值返回到颤振并显示结果,但它们还差得很远。使用相同的安卓手机,结果完全不同,而且很遥远。

我怀疑该缺陷与将 CameraImage 数据格式转换为位图有关,因为它是整个链中唯一我无法独立测试的部分。如果遇到类似问题的任何人都可以提供帮助,我感到很困惑。

标签: fluttertensorflow-liteflutter-pluginflutter-platform-channelflutter-android

解决方案


我认为原因是因为matrix.postRotate()方法需要一个整数,但你给它一个浮点数,所以你有一个从浮点数到整数的隐式转换,这把它搞砸了。


推荐阅读