Novità sul prodotto

Illumina i feed della videocamera in tempo reale con la funzionalità Luminosità Migliorata

Lettura di 7 minuti
Donovan McMurray
Ingegnere per le relazioni con gli sviluppatori

Di recente abbiamo condiviso come Instagram ha consentito agli utenti di scattare foto straordinarie in condizioni di scarsa illuminazione utilizzando la modalità notturna. Questa funzionalità è perfetta per le immagini statiche, in cui è possibile combinare più esposizioni per creare uno scatto statico di alta qualità. Ma cosa succede nei momenti tra le foto? Gli utenti devono interagire con la videocamera non solo nel momento in cui viene premuto il pulsante di scatto. Utilizzano anche l'anteprima per comporre la scena o scansionare i codici QR.

Oggi approfondiremo la funzionalità Low Light Boost (LLB), una potente funzionalità progettata per illuminare gli stream della videocamera in tempo reale. A differenza della modalità notturna, che richiede una durata di acquisizione fissa, la funzionalità Luminosità Migliorata funziona istantaneamente sull'anteprima live e sulle registrazioni video. La funzionalità Luminosità Migliorata regola automaticamente la quantità di illuminazione necessaria in base alla luce disponibile, quindi è ottimizzata per ogni ambiente.

Con un recente aggiornamento, la funzionalità Luminosità Migliorata consente agli utenti di Instagram di allineare lo scatto perfetto, mentre l'implementazione della modalità notturna esistente produce foto di alta qualità in condizioni di scarsa illuminazione, di cui gli utenti usufruiscono da oltre un anno.

Perché la luminosità in tempo reale è importante

Mentre la modalità notturna mira a migliorare la qualità dell'immagine finale, la funzionalità Luminosità Migliorata è pensata per l'usabilità e l'interattività in ambienti bui. Un altro fattore importante da considerare è che, anche se funzionano molto bene insieme, puoi utilizzare la funzionalità Luminosità Migliorata e la modalità notturna in modo indipendente e, in alcuni di questi casi d'uso, la funzionalità Luminosità Migliorata ha un valore a sé stante quando non sono necessarie le foto in modalità notturna. Ecco come la funzionalità Luminosità Migliorata migliora l'esperienza utente:

  • Inquadratura e acquisizione migliori: nelle scene poco illuminate, un'anteprima standard della videocamera può essere completamente nera. La funzionalità Luminosità Migliorata illumina il mirino, consentendo agli utenti di vedere effettivamente ciò che stanno inquadrando prima di premere il pulsante di scatto. Per questa esperienza, puoi utilizzare la modalità notturna per ottenere foto di qualità migliore in condizioni di scarsa illuminazione oppure puoi lasciare che la funzionalità Luminosità Migliorata fornisca all'utente un risultato fotografico "ciò che vedi è ciò che ottieni".
  • Scansione affidabile: i codici QR sono ovunque, ma scansionarli in un ristorante buio o in un parcheggio è spesso frustrante. Con un feed della videocamera notevolmente più luminoso, gli algoritmi di scansione possono rilevare e decodificare in modo affidabile i codici QR anche in ambienti molto bui.
  • Interazioni migliorate: per le app che prevedono interazioni video in diretta (come gli assistenti AI o le videochiamate), la funzionalità Luminosità Migliorata aumenta la quantità di informazioni percepibili, garantendo che i modelli di visione artificiale abbiano dati sufficienti su cui lavorare.

La differenza in Instagram

LLB_IG_demo_white_background.gif

Il team di ingegneri che lavora all'app Android di Instagram è sempre impegnato a fornire un'esperienza di videocamera all'avanguardia per i propri utenti. Nell'esempio sopra puoi vedere la differenza che la funzionalità Luminosità Migliorata fa su un Pixel 10 Pro. 

lowlight.png

È facile immaginare la differenza che fa nell'esperienza utente. Se gli utenti non riescono a vedere ciò che stanno acquisendo, è più probabile che abbandonino l'acquisizione. 

lowlight1.png

Scegliere l'implementazione

Esistono due modi per implementare la funzionalità Luminosità Migliorata per offrire la migliore esperienza sulla più ampia gamma di dispositivi:

  1. Modalità AE Luminosità Migliorata: si tratta di una modalità di esposizione automatica a livello hardware. Offre la massima qualità e prestazioni perché ottimizza direttamente la pipeline del processore di immagine (ISP). Controlla sempre prima questa modalità.
  2. Luminosità Migliorata di Google: se il dispositivo non supporta la modalità AE, puoi utilizzare questa soluzione basata su software fornita da Google Play Services. Applica la post-elaborazione allo stream della videocamera per illuminarlo. Trattandosi di una soluzione completamente software, è disponibile su più dispositivi, quindi questa implementazione ti aiuta a raggiungere più dispositivi con la funzionalità Luminosità Migliorata.

Modalità AE Luminosità Migliorata (hardware)

Meccanismo:
questa modalità è supportata sui dispositivi con Android 15 e versioni successive e richiede che l'OEM abbia implementato il supporto in HAL (attualmente disponibile sui dispositivi Pixel 10). Si integra direttamente con il processore di immagine (ISP) della fotocamera. Se imposti CaptureRequest.CONTROL_AE_MODE su CameraMetadata.CONTROL_AE_MODE_ON_LOW_LIGHT_BOOST_BRIGHTNESS_PRIORITY, il sistema della videocamera prende il controllo.

Comportamento:
HAL/ISP analizza la scena e regola i parametri del sensore e dell'elaborazione, spesso aumentando il tempo di esposizione, per illuminare l'immagine. In questo modo è possibile ottenere frame con un rapporto segnale/rumore (SNR) notevolmente migliorato, perché il tempo di esposizione esteso, anziché un aumento del guadagno del sensore digitale (ISO), consente al sensore di acquisire più informazioni sulla luce.

Vantaggio:
qualità dell'immagine e efficienza energetica potenzialmente migliori, in quanto sfrutta i percorsi hardware dedicati.

Compromesso:
potrebbe comportare una frequenza fotogrammi inferiore in condizioni di scarsa illuminazione, poiché il sensore ha bisogno di più tempo per acquisire la luce. La frequenza fotogrammi può scendere fino a 10 FPS in condizioni di scarsa illuminazione.

Luminosità Migliorata di Google (software tramite Google Play Services)

Meccanismo:
questa soluzione, distribuita come modulo facoltativo tramite Google Play Services, applica la post-elaborazione allo stream della videocamera. Utilizza una sofisticata tecnologia di miglioramento delle immagini in tempo reale chiamata HDRNet.

HDRNet di Google:
questo modello di deep learning analizza l'immagine a una risoluzione inferiore per prevedere un insieme compatto di parametri (una griglia bilaterale). Questa griglia guida quindi il miglioramento efficiente e spazialmente variabile dell'immagine a piena risoluzione sulla GPU. Il modello è addestrato per illuminare e migliorare la qualità dell'immagine in condizioni di scarsa illuminazione, con particolare attenzione alla visibilità del viso.

Orchestrazione del processo:
il modello HDRNet e la logica che lo accompagna sono orchestrati dal processore Luminosità Migliorata. Ecco alcuni esempi:

  1. Analisi della scena:
    un calcolatore personalizzato che stima la luminosità reale della scena utilizzando i metadati della videocamera (sensibilità del sensore, tempo di esposizione e così via) e il contenuto dell'immagine. Questa analisi determina il livello di miglioramento.
  2. Elaborazione HDRNet:
    applica il modello HDRNet per illuminare il frame. Il modello utilizzato è ottimizzato per le scene in condizioni di scarsa illuminazione e per le prestazioni in tempo reale.
  3. Fusione:
    i frame originali ed elaborati da HDRNet vengono uniti. La quantità di fusione applicata è controllata dinamicamente dal calcolatore della luminosità della scena, garantendo una transizione fluida tra gli stati con e senza miglioramento.
low-light-boost-processor-diagram.png

Vantaggio:
funziona su una gamma più ampia di dispositivi (attualmente supporta Samsung S22 Ultra, S23 Ultra, S24 Ultra, S25 Ultra e Pixel 6-9) senza richiedere un supporto HAL specifico. Mantiene la frequenza fotogrammi della videocamera perché è un effetto di post-elaborazione.

Compromesso:
trattandosi di un metodo di post-elaborazione, la qualità è limitata dalle informazioni presenti nei frame forniti dal sensore. Non è in grado di recuperare i dettagli persi a causa dell'oscurità estrema a livello del sensore.

Offrendo percorsi hardware e software, la funzionalità Luminosità Migliorata fornisce una soluzione scalabile per migliorare le prestazioni della videocamera in condizioni di scarsa illuminazione nell'ecosistema Android. Gli sviluppatori devono dare la priorità alla modalità AE, se disponibile, e utilizzare la funzionalità Luminosità Migliorata di Google come fallback affidabile.

Implementare la funzionalità Luminosità Migliorata nella tua app

Ora vediamo come implementare entrambe le offerte di Luminosità Migliorata. Puoi implementare i passaggi seguenti sia che utilizzi CameraX sia Camera2 nella tua app. Per risultati ottimali, ti consigliamo di implementare sia il passaggio 1 sia il passaggio 2.

Passaggio 1: modalità AE Luminosità Migliorata

Disponibile su alcuni dispositivi con Android 15 e versioni successive, la modalità AE Luminosità Migliorata funziona come una modalità di esposizione automatica (AE) specifica.

1. Verifica la disponibilità

Innanzitutto, controlla se il dispositivo della videocamera supporta la modalità AE Luminosità Migliorata.

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

2. Attiva la modalità

Se supportata, puoi attivare la modalità AE Luminosità Migliorata utilizzando l'oggetto CameraControl di 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. Monitora lo stato

Il fatto che tu abbia richiesto la modalità non significa che sia attualmente "in miglioramento". Il sistema attiva il miglioramento solo quando la scena è effettivamente buia. Puoi configurare un Observer per aggiornare l'UI (ad esempio mostrando un'icona a forma di luna) o convertire in un flusso utilizzando la funzione di estensione asFlow().

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

Puoi leggere la guida completa sulla modalità AE Luminosità Migliorata qui qui.

Passaggio 2: Luminosità Migliorata di Google

Per i dispositivi che non supportano la modalità AE hardware, la funzionalità Luminosità Migliorata di Google funge da fallback potente. Utilizza LowLightBoostSession per intercettare e illuminare lo stream.

1. Aggiungi dipendenze

Questa funzionalità viene fornita tramite 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. Inizializza il client

Prima di avviare la videocamera, utilizza LowLightBoostClient per assicurarti che il modulo sia installato e che il dispositivo sia supportato.

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 sessione Luminosità Migliorata

La funzionalità Luminosità Migliorata di Google elabora ogni frame, quindi devi fornire la superficie di visualizzazione a LowLightBoostSession, che ti restituisce una superficie a cui è stata applicata l'illuminazione. Per le app Camera2, puoi aggiungere la superficie risultante con CaptureRequest.Builder.addTarget(). Per CameraX, questa pipeline di elaborazione si allinea meglio alla classe CameraEffect, in cui puoi applicare l'effetto con un SurfaceProcessor e fornirlo di nuovo all'anteprima con un SurfaceProvider, come mostrato in questo codice.

// 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. Trasmetti i metadati

Affinché l'algoritmo funzioni, deve analizzare lo stato di esposizione automatica della videocamera. Devi restituire i risultati dell'acquisizione alla sessione Luminosità Migliorata. In CameraX, puoi farlo estendendo 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)
    }
  }
)

I passaggi di implementazione dettagliati per il client e la sessione sono disponibili nella guida alla funzionalità Luminosità Migliorata di Google.

Passaggi successivi

Implementando queste due opzioni, ti assicuri che gli utenti possano vedere chiaramente, scansionare in modo affidabile e interagire in modo efficace, indipendentemente dalle condizioni di illuminazione.

Per vedere queste funzionalità in azione all'interno di una codebase completa e pronta per la produzione, consulta l' app Jetpack Camera su GitHub. Implementa sia la modalità AE Luminosità Migliorata sia la funzionalità Luminosità Migliorata di Google, fornendoti un riferimento per la tua integrazione. 

Scritto da:

Continua a leggere