Analisar imagens

O caso de uso de análise de imagem oferece ao seu app uma imagem acessível por CPU para realizar processamento de imagens, visão computacional ou inferência de aprendizagem de máquina. O aplicativo implementa um método de análise executado em cada frame.

Implementação

As imagens são processadas por meio de um método que usa um parâmetro ImageProxy e um parâmetro de rotação ao método setAnalyzer().

O exemplo de código a seguir mostra como fazer isso e como vincular o caso de uso de análise de imagem e um caso de uso de visualização ao LifecycleOwner. Para ler sobre a criação de casos de usos de visualização, consulte Implementar uma visualização.

Quando esse método for retornado, a referência da imagem será fechada. Portanto, o método completará a análise ou fará uma cópia, em vez de passar a referência da imagem para além do método de análise.

A análise de imagem pode ser feita de duas maneiras: com ou sem bloqueio. O modo de bloqueio é configurado usando ImageAnalysis.ImageReaderMode.ACQUIRE_NEXT_IMAGE. Nesse modo, o Analyzer recebe frames da câmera em ordem sequencial. Isso significa que, se o método analyze demorar mais que a latência de um único frame na taxa atual, os frames poderão não estar mais atualizados porque os novos serão impedidos de entrar no pipeline até o retorno do método.

O modo sem bloqueio é configurado usando ImageAnalysis.ImageReaderMode.ACQUIRE_LATEST_IMAGE. Nesse modo, o Analyzer recebe o último frame disponível da câmera no momento em que o método analyze é chamado. Se o método demorar mais que a latência de um único frame na taxa atual, alguns frames poderão ser ignorados para que, na próxima vez em que o analyze receber dados, ele tenha o último frame disponível no pipeline da câmera. Defina o método de análise a ser executado em um gerenciador de callback usando ImageAnalysisConfig.Builder.setCallbackHandler, que permite que o restante do pipeline seja executado simultaneamente com a função do analisador. Se nenhum gerenciador for definido, o método de análise será executado na linha de execução principal.

Kotlin

    val imageAnalysisConfig = ImageAnalysisConfig.Builder()
        .setTargetResolution(Size(1280, 720))
        .setImageReaderMode(ImageAnalysis.ImageReaderMode.ACQUIRE_LATEST_IMAGE)
        .build()
    val imageAnalysis = ImageAnalysis(imageAnalysisConfig)

    imageAnalysis.setAnalyzer({ image: ImageProxy, rotationDegrees: Int ->
        // insert your code here.
    })

    CameraX.bindToLifecycle(this as LifecycleOwner, imageAnalysis, preview)
    

Java

    ImageAnalysisConfig config =
        new ImageAnalysisConfig.Builder()
            .setTargetResolution(new Size(1280, 720))
            .setImageReaderMode(ImageAnalysis.ImageReaderMode.ACQUIRE_LATEST_IMAGE)
            .build();

    ImageAnalysis imageAnalysis = new ImageAnalysis(config);

    imageAnalysis.setAnalyzer(
        new ImageAnalysis.Analyzer() {
            @Override
            public void analyze(ImageProxy image, int rotationDegrees) {
                // insert your code here.
            }
    });

    CameraX.bindToLifecycle((LifecycleOwner) this, imageAnalysis, preview);
    

O CameraX produz imagens no formato YUV_420_888.

Outros recursos

Para saber mais sobre o CameraX, consulte os seguintes recursos.

Codelab

  • Primeiros passos com o CameraX (link em inglês)
  • Amostra de código

  • App de amostra oficial do CameraX (link em inglês)