CameraX | Включение / отключение анализа изображений

Я пытаюсь реализовать сканер штрих-кода с использованием библиотеки сканирования штрих-кода CameraX и ZXing.

Я написал собственный анализатор, который декодирует штрих-коды, и эти штрих-коды должны быть обработаны (логика обработки, очевидно, занимает некоторое время).

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

Моя базовая логика настройки:

    private fun setupCamera() {
        processCameraProvider.unbindAll()
        val camera = processCameraProvider.bindToLifecycle(
            this,
            CameraSelector.DEFAULT_BACK_CAMERA,
            buildPreviewUseCase(),
            buildImageAnalysisUseCase())
    }

    private fun buildPreviewUseCase(): Preview {
        return Preview.Builder()
            .setTargetRotation(cameraPreview.display.rotation)
            .build()
            .apply {
                previewSurfaceProvider = cameraPreview.previewSurfaceProvider
            }
    }

    private fun buildImageAnalysisUseCase(): ImageAnalysis {
        return ImageAnalysis.Builder()
            .setTargetRotation(cameraPreview.display.rotation)
            .setBackpressureStrategy(ImageAnalysis.STRATEGY_KEEP_ONLY_LATEST)
            .build()
            .apply {
                setAnalyzer(Executors.newSingleThreadExecutor(),
                    ZxingBarcodeAnalyzer { qrResult ->
                        Handler(Looper.getMainLooper()).post {
                            viewModel.handleBarcode(qrResult.text)
                        }
                    })
            }
    }

Покопавшись в источниках библиотеки, я все еще не понимаю, как добиться желаемого поведения?

Если я вызываю unbind(imageAnalysisUseCase object) на processCameraProvider, я не могу снова связать этот объект (processCameraProvider имеет только метод bindToLifecycle(), а не bind(imageAnalysisUseCase object)).

Вызов clearAnalyzer() на ImageAnalysis полностью сбрасывает анализ изображения, несмотря на повторный вызов setAnalyzer().


person c0nst    schedule 20.02.2020    source источник
comment
Удалось заставить его работать?   -  person Balasubramanian    schedule 06.01.2021


Ответы (3)


есть проблема с clearAnalyzer()

Я использую вот так, пока не исправлю:

  fun enableAnalysis(enable: Boolean) {
    if (!enable) {
        isAnalyzerSet = false
        imageAnalysisUseCase?.clearAnalyzer()
        imageAnalysisUseCase.setAnalyzer(analysisExecutor, ImageAnalysis.Analyzer { })

    } else {
        if (isAnalyzerSet) return
        isAnalyzerSet = true
        imageAnalysisUseCase?.setAnalyzer(analysisExecutor, analyzer)
    }
}
person Sz-Nika Janos    schedule 05.03.2020
comment
В какой версии проблема? - person Matthias Wiedemann; 31.12.2020
comment
У меня была такая же проблема с перезапуском анализатора, который не работал. Моя проблема заключалась в том, что я не делал imageProxy.close () - person Matthias Wiedemann; 01.01.2021

Если все, что вам нужно сделать, это не обрабатывать изображения во время обработки изображения, вы можете установить тег внутри метода анализа, который немедленно возвращается, если изображение обрабатывается. Что-то вроде этого:

class MyViewModel: ViewModel() {

    private var isProcessing = false

    fun handleBarcode(text: String) {
        if (isProcessing) {
            return
        }
        // Do your processing here.
    }
}

Если вы вызовете processCameraProvider.unbind(imageAnalysis), вы можете снова связать вариант использования, вызвав processCameraProvider.bindToLifecycle(, , imageAnalysis), используя тот же экземпляр, но я не уверен, что это сработает. Повторная привязка того же экземпляра варианта использования Preview не работает, я не уверен, применимо ли это правило к ImageAnalysis.

person Husayn Hakeem    schedule 08.03.2020

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

ImageAnalysis imageAnalysis = imageAnalysisBuilder.setBackpressureStrategy(ImageAnalysis.STRATEGY_BLOCK_PRODUCER).setImageQueueDepth(1).build();

Из документов https://developer.android.com/reference/androidx/camera/core/ImageAnalysis#STRATEGY_BLOCK_PRODUCER

Запретить производителю создавать новые изображения.

Как только производитель произвел количество изображений, равное глубине очереди изображений, и ни одно из них не было закрыто, производитель прекратит создание изображений. Обратите внимание, что изображения могут быть поставлены в очередь внутри и не доставляться в анализатор до тех пор, пока последнее доставленное изображение не будет закрыто с помощью ImageProxy.close ()

person Emmanuel Osimosu    schedule 21.06.2021