Novedades sobre productos

Ilumina tus feeds de cámara en tiempo real con la mejora de baja luminosidad

Lectura de 7 min
Donovan McMurray
Ingeniera de Relaciones con Desarrolladores

Hace poco, compartimos cómo Instagram permitió a los usuarios tomar fotos increíbles con poca luz usando el Modo nocturno. Esta función es perfecta para imágenes fijas, en las que hay tiempo para combinar varias exposiciones y crear una toma estática de alta calidad. Pero ¿qué sucede con los momentos que ocurren entre las fotos? Los usuarios deben interactuar con la cámara más que solo en el momento en que se presiona el botón del obturador. También usan la vista previa para componer la escena o escanear códigos QR.

Hoy, analizaremos la mejora de baja luminosidad (LLB), una función potente diseñada para iluminar las transmisiones de cámara en tiempo real. A diferencia del Modo nocturno, que requiere una duración de captura fija, la mejora de baja luminosidad funciona de forma instantánea en la vista previa en vivo y las grabaciones de video. La LLB ajusta automáticamente la cantidad de iluminación necesaria según la luz disponible, por lo que está optimizada para todos los entornos.

Con una actualización reciente, la LLB permite a los usuarios de Instagram alinear la toma perfecta y, luego, su implementación existente del Modo nocturno da como resultado las mismas fotos de alta calidad con poca luz que sus usuarios disfrutan desde hace más de un año.

Por qué es importante el brillo en tiempo real

Si bien el Modo nocturno tiene como objetivo mejorar la calidad de la imagen final, la mejora de baja luminosidad está diseñada para la usabilidad y la interactividad en entornos oscuros. Otro factor importante que se debe tener en cuenta es que, aunque funcionan muy bien juntos, puedes usar la LLB y el Modo nocturno de forma independiente, y verás que, en algunos de estos casos de uso, la LLB tiene valor por sí sola cuando no se necesitan fotos en Modo nocturno. Así es como la LLB mejora la experiencia del usuario:

  • Mejor encuadre y captura: En escenas con poca luz, una vista previa de la cámara estándar puede ser completamente negra. La LLB ilumina el visor, lo que permite a los usuarios ver lo que están encuadrando antes de presionar el botón del obturador. Para esta experiencia, puedes usar el Modo nocturno para obtener el mejor resultado de fotos con poca luz o permitir que la LLB le dé al usuario un resultado de fotos de "lo que ves es lo que obtienes".
  • Escaneo confiable: Los códigos QR son omnipresentes, pero escanearlos en un restaurante oscuro o en un estacionamiento suele ser frustrante. Con un feed de la cámara mucho más brillante, los algoritmos de escaneo pueden detectar y decodificar códigos QR de manera confiable incluso en entornos muy oscuros.
  • Interacciones mejoradas: Para las apps que incluyen interacciones de video en vivo (como asistentes de IA o videollamadas), la LLB aumenta la cantidad de información perceptible, lo que garantiza que los modelos de visión por computadora tengan suficientes datos para trabajar.

La diferencia en Instagram

LLB_IG_demo_white_background.gif

El equipo de ingeniería detrás de la app de Instagram para Android siempre trabaja arduamente para brindar una experiencia de cámara de vanguardia a sus usuarios. En el ejemplo anterior, puedes ver la diferencia que hace la LLB en un Pixel 10 Pro. 

lowlight.png

Es fácil imaginar la diferencia que esto genera en la experiencia del usuario. Si los usuarios no pueden ver lo que están capturando, es más probable que abandonen la captura. 

lowlight1.png

Cómo elegir tu implementación

Hay dos formas de implementar la mejora de baja luminosidad para brindar la mejor experiencia en la mayor cantidad de dispositivos:

  1. Modo AE de mejora de baja luminosidad: Este es un modo de exposición automática de la capa de hardware. Ofrece la más alta calidad y el mejor rendimiento porque ajusta directamente la canalización del procesador de señales de imagen (ISP). Siempre verifica esto primero.
  2. Mejora de baja luminosidad de Google: Si el dispositivo no admite el modo AE, puedes recurrir a esta solución basada en software que proporcionan los Servicios de Google Play. Aplica el procesamiento posterior a la transmisión de la cámara para iluminarla. Como solución de software, está disponible en más dispositivos, por lo que esta implementación te ayuda a llegar a más dispositivos con la LLB.

Modo AE de mejora de baja luminosidad (hardware)

Mecanismo:
Este modo es compatible con dispositivos que ejecutan Android 15 y versiones posteriores, y requiere que el OEM haya implementado la compatibilidad en HAL (actualmente disponible en dispositivos Pixel 10). Se integra directamente con el procesador de señales de imagen (ISP) de la cámara. Si configuras CaptureRequest.CONTROL_AE_MODE en CameraMetadata.CONTROL_AE_MODE_ON_LOW_LIGHT_BOOST_BRIGHTNESS_PRIORITY, el sistema de la cámara toma el control.

Comportamiento:
El HAL/ISP analiza la escena y ajusta los parámetros del sensor y del procesamiento, lo que suele incluir el aumento del tiempo de exposición para iluminar la imagen. Esto puede generar fotogramas con una relación señal-ruido (SNR) significativamente mejorada, ya que el tiempo de exposición extendido, en lugar de un aumento en la ganancia del sensor digital (ISO), permite que el sensor capture más información de luz.

Ventaja:
Potencialmente, mejor calidad de imagen y eficiencia energética, ya que aprovecha las rutas de hardware dedicadas.

Compensación:
Puede generar una velocidad de fotogramas más baja en condiciones muy oscuras, ya que el sensor necesita más tiempo para capturar la luz. La velocidad de fotogramas puede disminuir hasta 10 FPS en condiciones de muy poca luz.

Mejora de baja luminosidad de Google (software a través de los Servicios de Google Play)

Mecanismo:
Esta solución, distribuida como un módulo opcional a través de los Servicios de Google Play, aplica el procesamiento posterior a la transmisión de la cámara. Usa una sofisticada tecnología de mejora de imágenes en tiempo real llamada HDRNet.

Google HDRNet:
Este modelo de aprendizaje profundo analiza la imagen con una resolución más baja para predecir un conjunto compacto de parámetros (una cuadrícula bilateral). Luego, esta cuadrícula guía la mejora eficiente y espacialmente variable de la imagen de resolución completa en la GPU. El modelo está entrenado para iluminar y mejorar la calidad de la imagen en condiciones de poca luz, con un enfoque en la visibilidad del rostro.

Orquestación de procesos:
El modelo HDRNet y su lógica acompañante están orquestados por el procesador de mejora de baja luminosidad. Esto incluye lo siguiente:

  1. Análisis de escenas:
    Una calculadora personalizada que estima el brillo real de la escena con metadatos de la cámara (sensibilidad del sensor, tiempo de exposición, etcétera) y contenido de la imagen. Este análisis determina el nivel de mejora.
  2. Procesamiento de HDRNet:
    Aplica el modelo HDRNet para iluminar el fotograma. El modelo que se usa está ajustado para escenas con poca luz y optimizado para el rendimiento en tiempo real.
  3. Combinación:
    Se combinan los fotogramas originales y los procesados por HDRNet. La cantidad de combinación aplicada se controla de forma dinámica con la calculadora de brillo de la escena, lo que garantiza una transición fluida entre los estados mejorados y no mejorados.
low-light-boost-processor-diagram.png

Ventaja:
Funciona en una gama más amplia de dispositivos (actualmente, es compatible con Samsung S22 Ultra, S23 Ultra, S24 Ultra, S25 Ultra y Pixel 6 a Pixel 9) sin requerir compatibilidad específica con HAL. Mantiene la velocidad de fotogramas de la cámara, ya que es un efecto de procesamiento posterior.

Compensación:
Como método de procesamiento posterior, la calidad está limitada por la información presente en los fotogramas que entrega el sensor. No puede recuperar los detalles perdidos debido a la oscuridad extrema a nivel del sensor.

Al ofrecer rutas de hardware y software, la mejora de baja luminosidad proporciona una solución escalable para mejorar el rendimiento de la cámara con poca luz en todo el ecosistema de Android. Los desarrolladores deben priorizar el modo AE cuando esté disponible y usar la mejora de baja luminosidad de Google como una alternativa sólida.

Cómo implementar la mejora de baja luminosidad en tu app

Ahora veamos cómo implementar ambas ofertas de LLB. Puedes implementar lo siguiente, ya sea que uses CameraX o Camera2 en tu app. Para obtener los mejores resultados, te recomendamos que implementes los pasos 1 y 2.

Paso 1: Modo AE de mejora de baja luminosidad

Disponible en dispositivos seleccionados que ejecutan Android 15 y versiones posteriores, el modo AE de LLB funciona como un modo de exposición automática (AE) específico.

1. Verifica la disponibilidad

Primero, verifica si el dispositivo de la cámara admite el modo AE de LLB.

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

2. Habilita el modo

Si es compatible, puedes habilitar el modo AE de LLB con el objeto CameraControl de 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. Supervisa el estado

El hecho de que hayas solicitado el modo no significa que esté "mejorando" actualmente. El sistema solo activa la mejora cuando la escena está realmente oscura. Puedes configurar un Observer para actualizar tu IU (como mostrar un ícono de luna) o convertir a un Flow con la función de extensión asFlow().

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

Puedes leer la guía completa sobre el modo AE de mejora de baja luminosidad aquí.

Paso 2: Mejora de baja luminosidad de Google

Para los dispositivos que no admiten el modo AE de hardware, la mejora de baja luminosidad de Google actúa como una alternativa potente. Usa LowLightBoostSession para interceptar e iluminar la transmisión.

1. Agrega dependencias

Esta función se entrega a través de los Servicios de Google Play.

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. Inicializa el cliente

Antes de iniciar la cámara, usa LowLightBoostClient para asegurarte de que el módulo esté instalado y de que el dispositivo sea compatible.

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. Crea una sesión de LLB

La LLB de Google procesa cada fotograma, por lo que debes darle a tu pantalla Surface a LowLightBoostSession, y te devuelve una Surface que tiene aplicada la iluminación. Para las apps de Camera2, puedes agregar la Surface resultante con CaptureRequest.Builder.addTarget(). En el caso de CameraX, esta canalización de procesamiento se alinea mejor con la clase CameraEffect, en la que puedes aplicar el efecto con un SurfaceProcessor y proporcionarlo a tu vista previa con un SurfaceProvider, como se muestra en este 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. Pasa los metadatos

Para que el algoritmo funcione, debe analizar el estado de exposición automática de la cámara. Debes pasar los resultados de captura a la sesión de LLB. En CameraX, esto se puede hacer extendiendo tu Preview.Builder con 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)
    }
  }
)

Puedes encontrar los pasos detallados de implementación para el cliente y la sesión en la guía de la mejora de baja luminosidad de Google.

Próximos pasos

Si implementas estas dos opciones, te aseguras de que tus usuarios puedan ver con claridad, escanear de manera confiable e interactuar de manera eficaz, independientemente de las condiciones de iluminación.

Para ver estas funciones en acción dentro de una base de código completa y lista para producción, consulta la app de cámara de Jetpack en GitHub. Implementa tanto el modo AE de LLB como la LLB de Google, lo que te brinda una referencia para tu propia integración. 

Escrito por:

Seguir leyendo