Flutter - Попытка использовать Tensorflowlite - FloatEfficientNet

Я пытаюсь использовать модель, которая успешно выводится как в собственном Swift, так и в android / java, чтобы сделать то же самое во флаттере, особенно в его стороне Android.

В этом случае значения, которые я получаю, неверны.

Что я сделал до сих пор:

  1. Я взял пример репозитория на github для tenorflowlite android:https://github.com/tensorflow/examples/tree/master/lite/examples/image_classification/android и обнаружил, что параметр FloatEfficientNet точно дает значения для моей модели.

  2. Я взял библиотеку flutter_tflite и изменил ее так, чтобы секция вывода кода Android соответствовала приведенному выше примеру tenorflow:https://github.com/shaqian/flutter_tflite

  3. Я использовал это руководство и включил репо, которое использует указанную выше библиотеку для вывода тензорного потока через канал платформы:https://github.com/flutter-devs/tensorflow_lite_flutter

В руководстве по флаттеру я использую плагин камеры, который может передавать объекты CameraImage из прямой трансляции камеры. Я передаю это в модифицированную библиотеку тензорного потока флаттера, которая использует канал платформы для передачи изображения на уровень Android. Он представляет собой список массивов байтов. (3 самолета, YuvImage). Пример tenorflow android (1) с рабочим кодом floatefficientnet, примеры Bitmap. Итак, я использую этот метод для преобразования:

          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;
    }

Вывод успешен, я могу вернуть значения обратно, чтобы они дрожали, и отображали результаты, но они не верны. При использовании того же телефона Android результаты будут совершенно разными и далекими.

Я подозреваю, что ошибка связана с преобразованием формата данных CameraImage в Bitmap, поскольку это единственный фрагмент всей цепочки, который я не могу независимо протестировать. Если кто-то, кто сталкивался с подобной проблемой, мог бы помочь, я очень озадачен.

1 ответ

Я думаю, причина в том, что matrix.postRotate() метод ожидает целое число, но вы даете ему число с плавающей запятой, поэтому у вас есть неявное преобразование из числа с плавающей запятой в целое число, которое портит его.

Другие вопросы по тегам