Поддержка FirebaseVisionImage / ML Toolkit cropRect()

Я публикую этот вопрос по запросу инженера 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:

  1. Определите поведение, которое я должен ожидать в отношении cropRect, и задокументируйте его более явно
  2. Объясните хотя бы немного о том, как изображения обрабатываются этими распознавателями. Почему так настойчиво использовать YUV_420_488? Может быть, для декодирования используется только канал Y? Разве распознаватель не должен конвертировать в RGBA внутри? Если так, то почему он злится на меня, когда я кормлю в растровых изображениях?
  3. Сделайте так, чтобы эти распознаватели либо обращали внимание на cropRect, либо заявляли, что они этого не делают, и предоставляли другой способ заставить эти распознаватели работать с подмножеством изображения, чтобы я мог получить производительность (надежность и скорость), которую можно было бы ожидать из необходимости ML коррелировать / трансформировать / что-либо меньшее изображение.

--Крис

0 ответов

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