Лучшее использование CameraX для распознавания текста MLKit на Android - PullRequest
1 голос
/ 01 марта 2020

Мне нужно реализовать распознавание текста с помощью MLKit на Android, и я решил использовать новый CameraX api в качестве библиотеки lib. Я борюсь с правильным «конвейером» классов или потоков данных изображения, потому что CameraX довольно новый и не так много ресурсов. Вариант использования: я делаю снимок, обрезаю его посередине на несколько границ, видимых в пользовательском интерфейсе, а затем передаю это обрезанное изображение в MLKit, который будет обрабатывать изображение.

Учитывая это, есть ли место для ImageAnalysis.Analyzer api? Насколько я понимаю, этот анализатор используется только для предварительного просмотра, а не захваченного изображения.

Моей первой идеей было использование takePicture метода, который принимает OnImageCapturedCallback, но когда я попробовал доступ, например. ImageProxy.height приложение зависло с исключением java.lang.IllegalStateException: Image is already closed, и я не смог найти никакого решения для этого.

Тогда я решил использовать другую перегрузку takePicture , и теперь я сохраняю Изображение в файл, затем прочитайте его в Bitmap, обрежьте это изображение, и теперь у меня есть изображение, которое можно передать в MLKit. Но когда я смотрю на FirebaseVisionImage, который передается FirebaseVisionTextRecognizer, у него есть фабричный метод , в который я могу передать изображение, которое я получаю из OnImageCapturedCallback, которое кажется мне ненужным шаги.

Итак, мои вопросы:

  1. Есть ли какой-нибудь класс ( CaptureProcessor ?), который позаботится об обрезке полученного изображения? Я полагаю, что тогда я мог бы использовать OnImageCapturedCallback, где я получил бы уже обрезанное изображение.
  2. Должен ли я даже использовать ImageAnalysis.Analyzer, если я не выполняю обработку в реальном времени и выполняю постобработку?

Полагаю, я могу достичь того, чего хочу, с помощью моего текущего подхода, но я чувствую, что могу использовать гораздо больше CameraX, чем сейчас.

Спасибо!

1 Ответ

2 голосов
/ 08 марта 2020

Есть ли какой-нибудь класс (CaptureProcessor?), Который позаботится об обрезке снятого изображения?

Вы можете установить соотношение сторон обрезки после построения сценария использования ImageCapture, используя метод setCropAspectRatio(Rational). Этот метод обрезает центр повернутого выходного изображения. Так что в основном то, что вы получите после вызова takePicture(), - это то, о чем я думаю, вы просите.

Должен ли я даже использовать ImageAnalysis.Analyzer, если я не выполняю обработку в реальном времени и выполняю постобработка?

Нет, это не имеет смысла в вашем сценарии. Как вы упомянули, только при обработке изображений в реальном времени вы захотите использовать ImageAnalysis.Analyzer.

ps: мне было бы интересно увидеть код, который вы используете для takePicture(), который вызвал IllegalStateException ,

[Редактировать]

Взгляните на ваш код

imageCapture?.takePicture(executor, object : ImageCapture.OnImageCapturedCallback() {
    override fun onCaptureSuccess(image: ImageProxy) {
        // 1
        super.onCaptureSuccess(image)

        // 2
        Log.d("MainActivity", "Image captured: ${image.width}x${image.height}")
    }
})

В (1), если вы посмотрите на реализацию super.onCaptureSuccess(imageProxy), это на самом деле закрывает imageProxy, переданный методу. Доступ к ширине и высоте изображения в (2) вызывает исключение, которое является нормальным, так как изображение было закрыто. Документация гласит:

Приложение отвечает за вызов ImageProxy.close () для закрытия изображения.

Так что при использовании этого обратного вызова вам, вероятно, не следует вызывать super..., просто используйте imageProxy, затем, прежде чем вернуться из метода, закройте его вручную (ImageProxy.close()).

...