Я отправляю этот вопрос по запросу инженера Firebase.
Я использую Camera2 API в сочетании с видением Firebase-mlkit. Я использую как штрих-код, так и распознавание текста на платформе. Вещи, которые я пытаюсь декодировать, - это в основном этикетки на оборудовании. При тестировании приложения я обнаружил, что попытка сканировать все изображение с камеры дает смешанные результаты. Основная проблема в том, что поле зрения слишком широкое.
- Если в поле зрения есть несколько штрих-кодов, firebase возвращает несколько результатов. Вы можете обойти это, посмотрев на координаты и выбрав ближайшую к центру.
- При сканировании текста оно более или менее одинаково, за исключением того, что вы получаете несколько блоков, много раз неполных (вы получите пару букв здесь и там).
Вы не можете просто сузить режим камеры - для этого типа сканирования пользователь извлекает выгоду из "широкого" обзора камеры для выравнивания. Идеальная ситуация была бы, если бы у вас было изображение с камеры (скажем, ради аргумента, это 1920x1080), но только подмножество изображения передается в firebase-ml. Вы можете представить себе камеру, на которой есть направляющее окно, и вы ориентируете и масштабируете объект, который хотите отсканировать, внутри этого поля.
Вы можете выбрать, какой тип изображения поступает из Camera2 API, но firebase-ml выдает предупреждения, если вы выбираете что-либо кроме YUV_420_488. Проблема заключается в том, что в Android API нет отличного способа работать с изображениями YUV, если вы сами этого не сделаете. Это то, что я в итоге и сделал - я решил свою проблему, написав Renderscript, который принимает входной YUV, преобразует его в RGBA, обрезает его, а затем применяет любое вращение, если это необходимо. В результате получается растровое изображение, которое я затем передаю либо в FirebaseVisionBarcodeDetectorOptions, либо в FirebaseVisionTextRecognizer.
Обратите внимание, что само растровое изображение вызывает предупреждения времени выполнения mlkit, побуждая меня использовать вместо этого формат YUV. Это возможно, но сложно. Вам нужно будет прочитать массив байтов и получить информацию из исходного изображения camera2 yuv и создать свой собственный. К сожалению, объект, который приходит из camear2, является классом, защищенным пакетами, поэтому вы не можете создать его подкласс или создать свой собственный экземпляр - вам, по сути, придется начинать с нуля. (Я уверен, что есть причина, по которой Google сделал этот класс защищенным, но это очень раздражает).
Шаги, которые я описал выше, работают, но с предупреждениями о формате от mlkit. Что делает его еще лучше, так это повышение производительности - сканер штрих-кода, работающий с изображением 800x300, занимает крошечную долю, если он занимает полноразмерное изображение!
Мне приходит в голову, что ничего из этого не понадобилось бы, если бы firebase обратил внимание на cropRect. В соответствии с API изображений, cropRect определяет, какая часть изображения является допустимой. Это свойство выглядит изменчивым, то есть вы можете получить изображение и изменить его cropRect после факта. Это звучит идеально. Я подумал, что могу получить Image из ImageReader, установить cropRect для подмножества этого изображения и передать его в Firebase, и что Firebase будет игнорировать все, что находится за пределами cropRect.
Кажется, это не так. Firebase, кажется, игнорирует cropRect. По моему мнению, firebase должен либо поддерживать cropRect, либо в документации должно быть явно указано, что он игнорирует его.
Мой запрос к команде firebase-mlkit:
- Определите поведение, которое я должен ожидать в отношении cropRect, и задокументируйте его более явно
- Объясните хотя бы немного о том, как изображения обрабатываются этими распознавателями. Почему так настойчиво использовать YUV_420_488? Может быть, для декодирования используется только канал Y? Разве распознаватель не должен конвертировать в RGBA внутри? Если так, то почему он злится на меня, когда я кормлю в растровых изображениях?
- Заставьте эти распознаватели либо обратить внимание на cropRect, либо заявите, что они этого не делают, и предоставьте другой способ заставить эти распознаватели работать с подмножеством изображения, чтобы я мог получить такую производительность (надежность и скорость), котораяожидал бы из-за того, что ML коррелирует / трансформирует / что-либо меньшее изображение.
- Крис