Flutter - Попытка использовать Tensorflowlite - FloatEfficientNet
Я пытаюсь использовать модель, которая успешно выводится как в собственном Swift, так и в android / java, чтобы сделать то же самое во флаттере, особенно в его стороне Android.
В этом случае значения, которые я получаю, неверны.
Что я сделал до сих пор:
Я взял пример репозитория на github для tenorflowlite android:https://github.com/tensorflow/examples/tree/master/lite/examples/image_classification/android и обнаружил, что параметр FloatEfficientNet точно дает значения для моей модели.
Я взял библиотеку flutter_tflite и изменил ее так, чтобы секция вывода кода Android соответствовала приведенному выше примеру tenorflow:https://github.com/shaqian/flutter_tflite
Я использовал это руководство и включил репо, которое использует указанную выше библиотеку для вывода тензорного потока через канал платформы: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()
метод ожидает целое число, но вы даете ему число с плавающей запятой, поэтому у вас есть неявное преобразование из числа с плавающей запятой в целое число, которое портит его.