Notícias sobre produtos

Ilumine as transmissões de câmera em tempo real com o modo pouca luz

Leitura de 7 minutos
Donovan McMurray
Engenheiro de relações com desenvolvedores

Recentemente, compartilhamos como o Instagram permitiu que os usuários tirassem fotos incríveis com pouca luz usando o modo noturno. Esse recurso é perfeito para imagens estáticas, em que há tempo para combinar várias exposições e criar uma foto estática de alta qualidade. Mas e os momentos que acontecem entre as fotos? Os usuários precisam interagir com a câmera mais do que apenas no momento em que o botão do obturador é pressionado. Eles também usam a visualização para compor a cena ou ler QR codes.

Hoje, vamos falar sobre o modo pouca luz (LLB, na sigla em inglês), um recurso poderoso projetado para iluminar transmissões de câmera em tempo real. Ao contrário do modo noturno, que exige uma duração de captura estática, o modo pouca luz funciona instantaneamente na visualização dinâmica e nas gravações de vídeo. O LLB ajusta automaticamente a quantidade de iluminação necessária com base na luz disponível, portanto, ele é otimizado para todos os ambientes.

Com uma atualização recente, o LLB permite que os usuários do Instagram alinhem a foto perfeita, e a implementação do modo noturno resulta nas mesmas fotos de alta qualidade com pouca luz que os usuários têm aproveitado há mais de um ano.

Por que o brilho em tempo real é importante

Embora o modo noturno tenha como objetivo melhorar a qualidade da imagem final, o Low Light Boost é destinado à usabilidade e interatividade em ambientes escuros. Outro fator importante a ser considerado é que, embora funcionem muito bem juntos, você pode usar o LLB e o modo noturno de forma independente. Em alguns desses casos de uso, o LLB tem valor por conta própria quando as fotos do modo noturno não são necessárias. Veja como o LLB melhora a experiência do usuário:

  • Melhor enquadramento e captura:em cenas com pouca luz, uma visualização padrão da câmera pode ser totalmente preta. O LLB ilumina o visor, permitindo que os usuários vejam o que estão enquadrando antes de pressionar o botão do obturador. Para essa experiência, você pode usar o modo noturno para obter o melhor resultado de foto com pouca luz ou permitir que o LLB ofereça ao usuário um resultado de foto "o que você vê é o que você recebe".
  • Leitura confiável:os QR codes são onipresentes, mas a leitura deles em um restaurante escuro ou em uma garagem de estacionamento é geralmente frustrante. Com uma transmissão da câmera significativamente mais brilhante, os algoritmos de leitura podem detectar e decodificar QR codes de forma confiável, mesmo em ambientes muito escuros.
  • Interações aprimoradas:para apps que envolvem interações de vídeo ao vivo (como assistentes de IA ou videochamadas), o LLB aumenta a quantidade de informações perceptíveis, garantindo que os modelos de visão computacional tenham dados suficientes para trabalhar.

A diferença no Instagram

LLB_IG_demo_white_background.gif

A equipe de engenharia por trás do app Android do Instagram está sempre trabalhando para oferecer uma experiência de câmera de ponta aos usuários. No exemplo acima, você pode ver a diferença que o LLB faz em um Pixel 10 Pro. 

lowlight.png

É fácil imaginar a diferença que isso faz na experiência do usuário. Se os usuários não conseguirem ver o que estão capturando, há uma chance maior de que eles abandonem a captura. 

lowlight1.png

Como escolher sua implementação

Há duas maneiras de implementar o Low Light Boost para oferecer a melhor experiência na maior variedade de dispositivos:

  1. Modo AE de melhoria de pouca luz:esse é um modo de exposição automática da camada de hardware. Ele oferece a mais alta qualidade e desempenho porque ajusta diretamente o pipeline do processador de sinal de imagem (ISP, na sigla em inglês). Sempre verifique isso primeiro.
  2. Melhoria de pouca luz do Google:se o dispositivo não for compatível com o modo AE, você poderá usar essa solução baseada em software fornecida pelo Google Play Services. Ele aplica o pós-processamento à transmissão da câmera para iluminá-la. Como uma solução totalmente de software, ela está disponível em mais dispositivos. Portanto, essa implementação ajuda você a alcançar mais dispositivos com o LLB.

Modo AE de melhoria de pouca luz (hardware)

Mecanismo:
Esse modo é compatível com dispositivos que executam o Android 15 e versões mais recentes e exige que o OEM tenha implementado o suporte no HAL (atualmente disponível em dispositivos Pixel 10). Ele se integra diretamente ao processador de sinal de imagem (ISP) da câmera. Se você definir CaptureRequest.CONTROL_AE_MODE como CameraMetadata.CONTROL_AE_MODE_ON_LOW_LIGHT_BOOST_BRIGHTNESS_PRIORITY, o sistema de câmera assumirá o controle.

Comportamento:
O HAL/ISP analisa a cena e ajusta os parâmetros do sensor e do processamento, geralmente incluindo o aumento do tempo de exposição, para iluminar a imagem. Isso pode gerar frames com uma relação sinal-ruído (SNR) significativamente melhorada, porque o tempo de exposição estendido, em vez de um aumento no ganho do sensor digital (ISO), permite que o sensor capture mais informações de luz.

Vantagem:
Qualidade de imagem e eficiência energética potencialmente melhores, já que aproveita caminhos de hardware dedicados.

Desvantagem:
Pode resultar em uma taxa de frames mais baixa em condições muito escuras, já que o sensor precisa de mais tempo para capturar a luz. A taxa de frames pode cair para até 10 QPS em condições de luz muito baixa.

Google Low Light Boost (software via Google Play Services)

Mecanismo:
Essa solução, distribuída como um módulo opcional pelo Google Play Services, aplica o pós-processamento à transmissão da câmera. Ele usa uma tecnologia sofisticada de aprimoramento de imagem em tempo real chamada HDRNet.

Google HDRNet:
Esse modelo de aprendizado profundo analisa a imagem em uma resolução mais baixa para prever um conjunto compacto de parâmetros (uma grade bilateral). Essa grade orienta o aprimoramento eficiente e espacialmente variável da imagem de resolução total na GPU. O modelo é treinado para iluminar e melhorar a qualidade da imagem em condições de pouca luz, com foco na visibilidade do rosto.

Orquestração de processos:
O modelo HDRNet e a lógica que o acompanha são orquestrados pelo processador Low Light Boost. Isso inclui:

  1. Análise de cena:
    Uma calculadora personalizada que estima o brilho real da cena usando metadados da câmera (sensibilidade do sensor, tempo de exposição etc.) e conteúdo da imagem. Essa análise determina o nível de aumento.
  2. Processamento do HDRNet:
    Aplica o modelo HDRNet para iluminar o frame. O modelo usado é ajustado para cenas com pouca luz e otimizado para desempenho em tempo real.
  3. Mesclagem:
    Os frames originais e processados pelo HDRNet são mesclados. A quantidade de mesclagem aplicada é controlada dinamicamente pela calculadora de brilho da cena, garantindo uma transição suave entre os estados aprimorados e não aprimorados.
low-light-boost-processor-diagram.png

Vantagem:
Funciona em uma variedade maior de dispositivos (atualmente oferece suporte ao Samsung S22 Ultra, S23 Ultra, S24 Ultra, S25 Ultra e Pixel 6 a Pixel 9) sem exigir suporte HAL específico. Mantém a frame rate da câmera, já que é um efeito de pós-processamento.

Desvantagem:
Como um método de pós-processamento, a qualidade é limitada pelas informações presentes nos frames entregues pelo sensor. Ele não pode recuperar detalhes perdidos devido à escuridão extrema no nível do sensor.

Ao oferecer caminhos de hardware e software, o Low Light Boost oferece uma solução escalonável para melhorar o desempenho da câmera com pouca luz em todo o ecossistema Android. Os desenvolvedores precisam priorizar o modo AE quando disponível e usar o Google Low Light Boost como um fallback robusto.

Implementar o modo pouca luz no seu app

Agora, vamos analisar como implementar as duas ofertas de LLB. Você pode implementar o seguinte, seja usando o CameraX ou o Camera2 no seu app. Para melhores resultados, recomendamos implementar as etapas 1 e 2.

Etapa 1: modo AE de melhoria de pouca luz

Disponível em dispositivos selecionados com o Android 15 e versões mais recentes, o modo AE do LLB funciona como um modo de exposição automática (AE) específico.

1. Verificar a disponibilidade

Primeiro, verifique se o dispositivo da câmera oferece suporte ao modo AE do LLB.

val cameraInfo = cameraProvider.getCameraInfo(cameraSelector)
val isLlbSupported = cameraInfo.isLowLightBoostSupported

2. Ativar o modo

Se houver suporte, você poderá ativar o modo AE do LLB usando o objeto CameraControl do CameraX.

// After setting up your camera, use the CameraInfo object to enable LLB AE Mode.
camera = cameraProvider.bindToLifecycle(...)

if (isLlbSupported) {
  try {
    // The .await() extension suspends the coroutine until the
    // ListenableFuture completes. If the operation fails, it throws
    // an exception which we catch below.
    camera?.cameraControl.enableLowLightBoostAsync(true).await()
  } catch (e: IllegalStateException) {
    Log.e(TAG, "Failed to enable low light boost: not available on this device or with the current camera configuration", e)
  } catch (e: CameraControl.OperationCanceledException) {
    Log.e(TAG, "Failed to enable low light boost: camera is closed or value has changed", e)
  }
}

3. Monitorar o estado

Só porque você solicitou o modo não significa que ele esteja "aumentando" no momento. O sistema só ativa o aumento quando a cena está realmente escura. Você pode configurar um observador para atualizar a interface (como mostrar um ícone de lua) ou converter para um fluxo usando a função de extensão asFlow().

if (isLlbSupported) {
  camera?.cameraInfo.lowLightBoostState.asFlow().collectLatest { state ->
    // Update UI accordingly
    updateMoonIcon(state == LowLightBoostState.ACTIVE)
  }
}

Leia o guia completo sobre o modo AE de melhoria de pouca luz aqui aqui.

Etapa 2: modo pouca luz do Google

Para dispositivos que não oferecem suporte ao modo AE de hardware, o Google Low Light Boost funciona como um fallback poderoso. Ele usa uma LowLightBoostSession para interceptar e iluminar a transmissão.

1. Adicionar dependências

Esse recurso é oferecido pelo Google Play Services.

implementation("com.google.android.gms:play-services-camera-low-light-boost:16.0.1-beta06")
// Add coroutines-play-services to simplify Task APIs
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-play-services:1.10.2")

2. Inicializar o cliente

Antes de iniciar a câmera, use o LowLightBoostClient para garantir que o módulo esteja instalado e que o dispositivo seja compatível.

val llbClient = LowLightBoost.getClient(context)

// Check support and install if necessary
val isSupported = llbClient.isCameraSupported(cameraId).await()
val isInstalled = llbClient.isModuleInstalled().await()

if (isSupported && !isInstalled) {
    // Trigger installation
    llbClient.installModule(installCallback).await()
}

3. Criar uma sessão do LLB

O LLB do Google processa cada frame. Portanto, você precisa fornecer a superfície de exibição para a LowLightBoostSession, e ela retorna uma superfície com a iluminação aplicada. Para apps Camera2, você pode adicionar a superfície resultante com CaptureRequest.Builder.addTarget(). Para o CameraX, esse pipeline de processamento se alinha melhor à classe CameraEffect, em que você pode aplicar o efeito com um SurfaceProcessor e fornecê-lo de volta à visualização com um SurfaceProvider, conforme mostrado neste código.

// With a SurfaceOutput from SurfaceProcessor.onSurfaceOutput() and a
// SurfaceRequest from Preview.SurfaceProvider.onSurfaceRequested(),
// create a LLB Session.
suspend fun createLlbSession(surfaceRequest: SurfaceRequest, outputSurfaceForLlb: Surface) {
  // 1. Create the LLB Session configuration
  val options = LowLightBoostOptions(
    outputSurfaceForLlb,
    cameraId,
    surfaceRequest.resolution.width,
    surfaceRequest.resolution.height,
    true // Start enabled
  )

  // 2. Create the session.
  val llbSession = llbClient.createSession(options, callback).await()

  // 3. Get the surface to use.
  val llbInputSurface = llbSession.getCameraSurface()

  // 4. Provide the surface to the CameraX Preview UseCase.
  surfaceRequest.provideSurface(llbInputSurface, executor, resultListener)

  // 5. Set the scene detector callback to monitor how much boost is being applied.
  val onSceneBrightnessChanged = object : SceneDetectorCallback {
    override fun onSceneBrightnessChanged(
      session: LowLightBoostSession,
      boostStrength: Float
    ) {
      // Monitor the boostStrength from 0 (no boosting) to 1 (maximum boosting)
    }
  }
  llbSession.setSceneDetectorCallback(onSceneBrightnessChanged, null)
}

4. Transmitir os metadados

Para que o algoritmo funcione, ele precisa analisar o estado de exposição automática da câmera. Você precisa transmitir os resultados da captura de volta para a sessão do LLB. No CameraX, isso pode ser feito estendendo o Preview.Builder com Camera2Interop.Extender.setSessionCaptureCallback().

Camera2Interop.Extender(previewBuilder).setSessionCaptureCallback(
  object : CameraCaptureSession.CaptureCallback() {
    override fun onCaptureCompleted(
      session: CameraCaptureSession,
      request: CaptureRequest,
      result: TotalCaptureResult
    ) {
      super.onCaptureCompleted(session, request, result)
      llbSession?.processCaptureResult(result)
    }
  }
)

As etapas detalhadas de implementação para o cliente e a sessão podem ser encontradas no guia do modo pouca luz do Google.

Próximas etapas

Ao implementar essas duas opções, você garante que os usuários possam ver com clareza, ler de forma confiável e interagir de maneira eficaz, independentemente das condições de iluminação.

Para conferir esses recursos em ação em uma base de código completa e pronta para produção, confira o app de câmera do Jetpack no GitHub. Ele implementa o modo AE do LLB e o LLB do Google, oferecendo uma referência para sua própria integração. 

Escrito por:

Continuar lendo