Wiadomości o usługach

Rozjaśnianie obrazu z kamery w czasie rzeczywistym dzięki funkcji doświetlania przy słabym oświetleniu

Czas czytania: 7 min
Donovan McMurray
Inżynier ds. relacji z deweloperami

Niedawno informowaliśmy jak Instagram umożliwia użytkownikom robienie wspaniałych zdjęć przy słabym oświetleniu za pomocą trybu nocnego. Ta funkcja doskonale sprawdza się w przypadku zdjęć statycznych, gdy jest czas na połączenie kilku ekspozycji w celu utworzenia statycznego zdjęcia wysokiej jakości. A co z momentami, które dzieją się między zdjęciami? Użytkownicy muszą wchodzić w interakcje z aparatem nie tylko w momencie naciśnięcia spustu migawki. Używają też podglądu do komponowania sceny lub skanowania kodów QR.

Dziś przyjrzymy się funkcji doświetlania przy słabym oświetleniu (LLB), która rozjaśnia obraz z kamery w czasie rzeczywistym. W przeciwieństwie do trybu nocnego, który wymaga dłuższego czasu naświetlania, funkcja doświetlania przy słabym oświetleniu działa natychmiast na podglądzie na żywo i nagraniach wideo. LLB automatycznie dostosowuje stopień rozjaśnienia w zależności od dostępnego światła, dzięki czemu jest zoptymalizowana pod kątem każdego otoczenia.

Dzięki niedawnej aktualizacji funkcja LLB umożliwia użytkownikom Instagrama ustawienie idealnego kadru, a następnie istniejąca implementacja trybu nocnego zapewnia taką samą wysoką jakość zdjęć przy słabym oświetleniu, z której użytkownicy korzystają już od ponad roku.

Dlaczego jasność w czasie rzeczywistym jest ważna

Tryb nocny ma na celu poprawę jakości końcowego obrazu, a funkcja doświetlania przy słabym oświetleniu – użyteczność i interaktywność w ciemnym otoczeniu. Warto też pamiętać, że choć te funkcje dobrze ze sobą współpracują, można ich używać niezależnie. W niektórych przypadkach funkcja LLB jest przydatna sama w sobie, gdy nie są potrzebne zdjęcia w trybie nocnym. Oto jak funkcja LLB zwiększa wygodę użytkowników:

  • Lepsze kadrowanie i rejestrowanie: w słabo oświetlonych scenach standardowy podgląd z kamery może być zupełnie czarny. LLB rozjaśnia wizjer, dzięki czemu użytkownicy mogą zobaczyć, co kadrują, zanim nacisną przycisk migawki. Aby uzyskać najlepszą jakość zdjęć przy słabym oświetleniu, możesz użyć trybu nocnego lub pozwolić funkcji LLB zapewnić użytkownikowi efekt „widzisz to, co dostajesz”.
  • Niezawodne skanowanie: kody QR są wszechobecne, ale ich skanowanie w ciemnej restauracji lub na parkingu jest często frustrujące. Dzięki znacznie jaśniejszemu przekazowi z kamery algorytmy skanowania mogą niezawodnie wykrywać i dekodować kody QR nawet w bardzo słabo oświetlonych miejscach.
  • Ulepszone interakcje: w przypadku aplikacji obejmujących interakcje z transmisją na żywo (takich jak asystenci AI czy rozmowy wideo) funkcja LLB zwiększa ilość informacji, które można dostrzec, dzięki czemu modele rozpoznawania obrazów mają wystarczająco dużo danych do pracy.

Różnica w Instagramie

LLB_IG_demo_white_background.gif

Zespół inżynierów pracujący nad aplikacją Instagram na Androida nieustannie pracuje nad tym, aby zapewnić użytkownikom najnowocześniejsze funkcje aparatu. Na powyższym przykładzie widać, jak dużą różnicę robi funkcja LLB na Pixelu 10 Pro. 

lowlight.png

Łatwo sobie wyobrazić, jak dużą różnicę robi to w przypadku wygody użytkowników. Jeśli użytkownicy nie widzą, co rejestrują, istnieje większe prawdopodobieństwo, że zrezygnują z rejestrowania. 

lowlight1.png

Wybór implementacji

Funkcję doświetlania przy słabym oświetleniu możesz zaimplementować na 2 sposoby, aby zapewnić najlepsze wrażenia na jak największej liczbie urządzeń:

  1. Tryb automatycznej ekspozycji z doświetlaniem przy słabym oświetleniu: jest to tryb automatycznej ekspozycji na poziomie sprzętu. Zapewnia najwyższą jakość i wydajność, ponieważ bezpośrednio dostraja potok procesora sygnału obrazu (ISP). Zawsze sprawdzaj to w pierwszej kolejności.
  2. Doświetlanie przy słabym oświetleniu Google: jeśli urządzenie nie obsługuje trybu automatycznej ekspozycji, możesz użyć tego rozwiązania programowego udostępnianego przez Usługi Google Play. Stosuje ono przetwarzanie końcowe do strumienia z kamery, aby go rozjaśnić. Jako rozwiązanie w całości programowe jest dostępne na większej liczbie urządzeń, dzięki czemu możesz dotrzeć do większej liczby urządzeń z funkcją LLB.

Tryb automatycznej ekspozycji z doświetlaniem przy słabym oświetleniu (sprzęt)

Mechanizm:
Ten tryb jest obsługiwany na urządzeniach z Androidem 15 i nowszymi wersjami. Wymaga też, aby producent OEM zaimplementował obsługę w HAL (obecnie dostępna na urządzeniach Pixel 10). Integruje się bezpośrednio z procesorem sygnału obrazu (ISP) aparatu. Jeśli ustawisz CaptureRequest.CONTROL_AE_MODE na CameraMetadata.CONTROL_AE_MODE_ON_LOW_LIGHT_BOOST_BRIGHTNESS_PRIORITY, system aparatu przejmie kontrolę.

Działanie:
HAL/ISP analizuje scenę i dostosowuje parametry czujnika i przetwarzania, często zwiększając czas naświetlania, aby rozjaśnić obraz. Może to dać klatki ze znacznie lepszym stosunkiem sygnału do szumu (SNR), ponieważ wydłużony czas naświetlania, a nie zwiększenie cyfrowego wzmocnienia czujnika (ISO), pozwala czujnikowi rejestrować więcej informacji o świetle.

Zaleta:
Potencjalnie lepsza jakość obrazu i energooszczędność, ponieważ wykorzystuje dedykowane ścieżki sprzętowe.

Wada:
W bardzo ciemnych warunkach może to spowodować niższą liczbę klatek na sekundę, ponieważ czujnik potrzebuje więcej czasu na rejestrowanie światła. W bardzo słabym oświetleniu liczba klatek na sekundę może spaść nawet do 10 FPS.

Doświetlanie przy słabym oświetleniu Google (oprogramowanie za pomocą Usług Google Play)

Mechanizm:
To rozwiązanie, rozpowszechniane jako opcjonalny moduł za pomocą Usług Google Play, stosuje przetwarzanie końcowe do strumienia z kamery. Wykorzystuje zaawansowaną technologię ulepszania obrazu w czasie rzeczywistym o nazwie HDRNet.

HDRNet Google:
Ten model uczenia głębokiego analizuje obraz w niższej rozdzielczości, aby przewidzieć kompaktowy zestaw parametrów (siatkę dwustronną). Ta siatka prowadzi następnie wydajne, przestrzenne ulepszanie obrazu w pełnej rozdzielczości na GPU. Model jest trenowany pod kątem rozjaśniania i poprawiania jakości obrazu w słabym oświetleniu, ze szczególnym uwzględnieniem widoczności twarzy.

Orkiestracja procesu:
Model HDRNet i towarzysząca mu logika są orkiestrowane przez procesor doświetlania przy słabym oświetleniu. Obejmuje to:

  1. Analiza sceny:
    niestandardowy kalkulator, który szacuje rzeczywistą jasność sceny na podstawie metadanych aparatu (czułość czujnika, czas naświetlania itp.) i treści obrazu. Ta analiza określa poziom doświetlania.
  2. Przetwarzanie HDRNet:
    stosuje model HDRNet, aby rozjaśnić klatkę. Używany model jest dostosowany do scen w słabym oświetleniu i zoptymalizowany pod kątem wydajności w czasie rzeczywistym.
  3. Mieszanie:
    oryginalne klatki i klatki przetworzone przez HDRNet są mieszane. Stopień mieszania jest dynamicznie kontrolowany przez kalkulator jasności sceny, co zapewnia płynne przejście między stanami z doświetlaniem i bez niego.
low-light-boost-processor-diagram.png

Zaleta:
Działa na szerszej gamie urządzeń (obecnie obsługuje Samsunga S22 Ultra, S23 Ultra, S24 Ultra, S25 Ultra oraz Pixele od 6 do 9) bez konieczności obsługi HAL. Utrzymuje liczbę klatek na sekundę, ponieważ jest to efekt przetwarzania końcowego.

Wada:
Jako metoda przetwarzania końcowego jakość jest ograniczona informacjami zawartymi w klatkach dostarczanych przez czujnik. Nie można odzyskać szczegółów utraconych z powodu ekstremalnej ciemności na poziomie czujnika.

Dzięki oferowaniu ścieżek sprzętowych i programowych funkcja doświetlania przy słabym oświetleniu zapewnia skalowalne rozwiązanie, które poprawia wydajność aparatu w słabym oświetleniu w całym ekosystemie Androida. Deweloperzy powinni w miarę możliwości priorytetowo traktować tryb automatycznej ekspozycji i używać doświetlania przy słabym oświetleniu Google jako niezawodnego rozwiązania rezerwowego.

Implementowanie doświetlania przy słabym oświetleniu w aplikacji

Przyjrzyjmy się teraz, jak zaimplementować obie oferty LLB. Możesz zaimplementować te funkcje niezależnie od tego, czy w aplikacji używasz CameraX czy Camera2. Aby uzyskać najlepsze wyniki, zalecamy zaimplementowanie zarówno kroku 1, jak i kroku 2.

Krok 1. Tryb automatycznej ekspozycji z doświetlaniem przy słabym oświetleniu

Dostępny na wybranych urządzeniach z Androidem 15 i nowszymi wersjami tryb automatycznej ekspozycji z doświetlaniem przy słabym oświetleniu działa jako konkretny tryb automatycznej ekspozycji.

1. Sprawdź dostępność

Najpierw sprawdź, czy urządzenie z aparatem obsługuje tryb automatycznej ekspozycji z doświetlaniem przy słabym oświetleniu.

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

2. Włącz tryb

Jeśli jest obsługiwany, możesz włączyć tryb automatycznej ekspozycji z doświetlaniem przy słabym oświetleniu za pomocą obiektu CameraControl w 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. Monitoruj stan

Samo zażądanie trybu nie oznacza, że jest on obecnie „doświetlany”. System aktywuje doświetlanie tylko wtedy, gdy scena jest rzeczywiście ciemna. Możesz skonfigurować obserwatora, aby aktualizować interfejs (np. wyświetlać ikonę księżyca) lub przekonwertować go na Flow za pomocą funkcji rozszerzenia asFlow().

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

Pełny przewodnik po trybie automatycznej ekspozycji z doświetlaniem przy słabym oświetleniu znajdziesz tutaj.

Krok 2. Doświetlanie przy słabym oświetleniu Google

W przypadku urządzeń, które nie obsługują sprzętowego trybu automatycznej ekspozycji, doświetlanie przy słabym oświetleniu Google działa jako niezawodne rozwiązanie rezerwowe. Używa LowLightBoostSession do przechwytywania i rozjaśniania obrazu.

1. Dodaj zależności

Ta funkcja jest udostępniana za pomocą Usług 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. Zainicjuj klienta

Zanim uruchomisz aparat, użyj LowLightBoostClient, aby sprawdzić, czy moduł jest zainstalowany i czy urządzenie jest obsługiwane.

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. Utwórz sesję LLB

Doświetlanie przy słabym oświetleniu Google przetwarza każdą klatkę, dlatego musisz przekazać powierzchnię wyświetlacza do LowLightBoostSession, a ona zwróci powierzchnię z zastosowanym rozjaśnieniem. W przypadku aplikacji Camera2 możesz dodać wynikową powierzchnię za pomocą CaptureRequest.Builder.addTarget(). W przypadku CameraX ten potok przetwarzania najlepiej pasuje do klasy CameraEffect, w której możesz zastosować efekt za pomocą SurfaceProcessor i przekazać go z powrotem do podglądu za pomocą SurfaceProvider, jak widać w tym kodzie.

// 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. Przekaż metadane

Aby algorytm działał, musi analizować stan automatycznej ekspozycji aparatu. Musisz przekazać wyniki rejestrowania z powrotem do sesji LLB. W CameraX można to zrobić, rozszerzając Preview.Builder za pomocą 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)
    }
  }
)

Szczegółowe instrukcje implementacji klienta i sesji znajdziesz w przewodniku po doświetlaniu przy słabym oświetleniu Google.

Następne kroki

Dzięki zaimplementowaniu tych 2 opcji użytkownicy będą mogli wyraźnie widzieć, niezawodnie skanować i skutecznie wchodzić w interakcje niezależnie od warunków oświetleniowych.

Aby zobaczyć te funkcje w działaniu w kompletnym, przygotowanym do zastosowań produkcyjnych kodzie, zapoznaj się z aplikacją Jetpack Camera w GitHub. Implementuje ona zarówno tryb automatycznej ekspozycji z doświetlaniem przy słabym oświetleniu, jak i doświetlanie przy słabym oświetleniu Google, co stanowi odniesienie do własnej integracji. 

Autor:

Czytaj dalej