Я использую декодер штрих-кода Firebase-ML в потоковом режиме (в режиме реального времени) с использованием Camera2 API. Я делаю так, чтобы настроить ImageReader, который периодически выдает мне изображения. Полное изображение - это разрешение моей камеры, поэтому оно большое - это 12-мегапиксельная камера.
Сканеру штрих-кода требуется около 0,41 секунды для обработки изображения на Samsung S7 Edge, поэтому я настроил ImageReaderListener для декодирования по одному и отбрасываю любые последующие кадры до завершения декодера.
Используемый мной формат изображения - YUV_420_888, потому что это то, что рекомендует документация, и потому, что если вы пытаетесь передать декодеру штрих-кода ML что-либо еще, на что он жалуется (сообщение времени выполнения для журнала отладки).
Все это работает, но я думаю, что если бы я мог обрезать изображение, оно работало бы лучше. Я хотел бы оставить разрешение камеры таким же (чтобы я мог отобразить широкий SurfaceView, чтобы помочь пользователю настроить свою камеру в соответствии со штрих-кодом), но я хочу дать Firebase обрезанную версию (в основном, центральный прямоугольник). Под «работать лучше» я подразумеваю в основном «быстрее», но я также хотел бы устранить отвлекающие факторы (особенно другие штрих-коды, которые могут быть на краю изображения).
Это заставило меня попытаться найти лучший способ обрезать изображение YUV, и я был удивлен, обнаружив, что очень мало помощи. Большинство примеров, которые я нашел в Интернете, выполняют многоэтапный процесс, в котором вы сначала конвертируете изображение YUV в JPEG, затем визуализируете JPEG в растровое изображение, а затем масштабируете его. Это имеет несколько проблем в моей голове
- Похоже, это будет иметь значительные последствия для производительности (в режиме реального времени). Это помогло бы мне выполнить несколько задач, включая снижение энергопотребления, улучшение времени отклика и более быстрый возврат изображений в ImageReader с помощью image.close ().
- Этот подход не возвращает вас к Image, поэтому вместо этого вам нужно подавать в Firebase растровое изображение, и это, похоже, не работает. Я не знаю, что делает внутренняя база данных, но я подозреваю, что она работает в основном (возможно, полностью) вне плоскости Y и что перевод, если Image -> JPEG -> Bitmap, запутывает это.
Я искал библиотеки YUV, которые могли бы помочь. В дикой природе есть что-то, называемое libyuv-android, но оно не работает точно в том формате, который хочет firebase-ml, и это связка JNI, которая вызывает у меня кроссплатформенность.
Мне интересно, подумал ли кто-нибудь еще об этом и придумал ли лучшее решение для обрезки изображений YUV_420_488 в Android. Я не могу найти это, потому что это относительно тривиальная операция? Есть шаг и прокладка, чтобы быть среди прочего среди прочего. Я не эксперт по изображениям и цветам, и мне кажется, что я не должен пытаться делать это сам, особенно меня беспокоит то, что я выясняю, что работает на моем устройстве, а не на других.
Обновление: это может быть спорным. В качестве эксперимента я посмотрел на изображение, которое возвращается из ImageReader. Это экземпляр ImageReader.SurfaceImage, который является закрытым (для ImageReader) классом. У этого также есть связка нативных связей. Таким образом, возможно, что единственный выбор - использовать метод сжатия / распаковки, который кажется неубедительным. Единственное, о чем я могу думать, - это принять решение самому использовать только плоскость Y и сделать из него растровое изображение, и посмотреть, все ли в порядке с Firebase-ML. Такой подход все еще кажется мне рискованным.