Wiadomości o usługach

Rozjaśnianie obrazu z kamery w czasie rzeczywistym za pomocą funkcji Low Light Boost

Czas czytania: 7 minut
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, gdzie jest czas na połączenie wielu ekspozycji w celu utworzenia wysokiej jakości zdjęcia. Ale co z chwilami, które zdarzają się między zdjęciami? Użytkownicy muszą wchodzić w interakcję z aparatem nie tylko w momencie naciśnięcia przycisku migawki. Używają też podglądu do komponowania sceny lub skanowania kodów QR.

Dziś przyjrzymy się bliżej funkcji Low Light Boost (LLB), która rozjaśnia strumienie wideo z kamery w czasie rzeczywistym. W przeciwieństwie do trybu nocnego, który wymaga dłuższego czasu naświetlania, ulepszona jakość obrazu przy słabym oświetleniu działa natychmiast w przypadku podglądu na żywo i nagrywania filmów. LLB automatycznie dostosowuje poziom rozjaśnienia do dostępnego światła, dzięki czemu jest zoptymalizowany pod kątem każdego otoczenia.

Dzięki niedawnej aktualizacji funkcja LLB umożliwia użytkownikom Instagrama idealne ustawienie kadru, a następnie wykorzystanie istniejącego trybu nocnego, który zapewnia zdjęcia wysokiej jakości przy słabym oświetleniu. Użytkownicy korzystają z tej funkcji 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 wzmocnienia przy słabym oświetleniu jest przeznaczona do użytku i interakcji w ciemnym otoczeniu. Kolejnym ważnym czynnikiem jest to, że chociaż te funkcje działają bardzo dobrze razem, możesz używać LLB i trybu nocnego niezależnie od siebie. W niektórych przypadkach LLB ma wartość sam w sobie, gdy zdjęcia w trybie nocnym nie są potrzebne. Oto jak LLB zwiększa wygodę użytkowników:

  • Lepsze kadrowanie i nagrywanie: w słabo oświetlonych scenach standardowy podgląd z kamery może być całkowicie czarny. LLB rozjaśnia wizjer, dzięki czemu użytkownicy mogą zobaczyć, co kadrują, zanim nacisną spust migawki. W tym przypadku możesz użyć trybu nocnego, aby uzyskać najlepszą jakość zdjęć przy słabym oświetleniu, lub pozwolić funkcji LLB na wyświetlenie zdjęcia „takie, jakie widzisz”.
  • Niezawodne skanowanie: kody QR są wszechobecne, ale skanowanie ich w ciemnej restauracji lub na parkingu często bywa frustrujące. Dzięki znacznie jaśniejszemu przekazowi z kamery algorytmy skanowania mogą niezawodnie wykrywać i dekodować kody QR nawet w bardzo słabym oświetleniu.
  • Ulepszone interakcje: w przypadku aplikacji, które obejmują interakcje wideo na żywo (np. asystenci AI lub połączenia wideo), LLB zwiększa ilość dostrzegalnych informacji, dzięki czemu modele widzenia komputerowego mają wystarczająco dużo danych do pracy.

Różnica na Instagramie

LLB_IG_demo_white_background.gif

Zespół inżynierów pracujący nad aplikacją Instagram na Androida nieustannie dba o to, aby użytkownicy mogli korzystać z najnowocześniejszych funkcji aparatu. Na powyższym przykładzie widać, jak dużą różnicę robi LLB w przypadku Pixela 10 Pro. 

lowlight.png

Łatwo sobie wyobrazić, jak bardzo wpływa to na wygodę użytkowników. Jeśli użytkownicy nie widzą tego, co nagrywają, istnieje większe prawdopodobieństwo, że zrezygnują z nagrywania. 

lowlight1.png

Wybór implementacji

Aby zapewnić jak najlepsze wrażenia na jak największej liczbie urządzeń, możesz wdrożyć funkcję Low Light Boost na 2 sposoby:

  1. Tryb automatycznej ekspozycji w słabym oświetleniu: to tryb automatycznej ekspozycji na poziomie sprzętowym. Zapewnia najwyższą jakość i wydajność, ponieważ bezpośrednio dostraja procesor sygnału obrazu (ISP). Zawsze najpierw sprawdzaj to.
  2. Wzmocnienie przy słabym oświetleniu od Google: jeśli urządzenie nie obsługuje trybu AE, możesz skorzystać z tego rozwiązania opartego na oprogramowaniu, które jest dostępne w Usługach Google Play. Stosuje przetwarzanie końcowe do strumienia z kamery, aby go rozjaśnić. Jest to rozwiązanie w całości oparte na oprogramowaniu, dlatego jest dostępne na większej liczbie urządzeń. Dzięki temu możesz docierać do większej liczby urządzeń z LLB.

Tryb AE ze wzmocnieniem przy słabym oświetleniu (sprzęt)

Mechanizm:
ten tryb jest obsługiwany na urządzeniach z Androidem 15 i nowszym. Wymaga on wdrożenia obsługi w HAL przez producenta OEM (obecnie dostępny na Pixelu 10). Jest on bezpośrednio zintegrowany z procesorem sygnału obrazu (ISP) kamery. Jeśli ustawisz parametr CaptureRequest.CONTROL_AE_MODE na wartość CameraMetadata.CONTROL_AE_MODE_ON_LOW_LIGHT_BOOST_BRIGHTNESS_PRIORITY, system aparatu przejmie kontrolę.

Zachowanie:
warstwa HAL/ISP analizuje scenę i dostosowuje parametry czujnika i przetwarzania, często zwiększając czas ekspozycji, aby rozjaśnić obraz. Dzięki temu można uzyskać klatki o znacznie lepszym stosunku sygnału do szumu, ponieważ dłuższy czas ekspozycji, a nie zwiększenie wzmocnienia cyfrowego czujnika (ISO), pozwala czujnikowi rejestrować więcej informacji o świetle.

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

Wada:
może skutkować niższą liczbą klatek na sekundę w bardzo ciemnych warunkach, 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.

Doświetlanie w słabym oświetleniu (oprogramowanie w Usługach Google Play)

Mechanizm:
to rozwiązanie, rozpowszechniane jako opcjonalny moduł za pomocą Usług Google Play, przetwarza strumień z kamery. Wykorzystuje zaawansowaną technologię ulepszania obrazu w czasie rzeczywistym o nazwie HDRNet.

Google HDRNet:
 ten model uczenia głębokiego analizuje obraz w niższej rozdzielczości, aby przewidzieć kompaktowy zestaw parametrów (siatkę dwustronną). Ta siatka służy następnie do efektywnego, przestrzennego ulepszania obrazu w pełnej rozdzielczości na procesorze graficznym. Model jest trenowany pod kątem rozjaśniania i poprawiania jakości obrazu w warunkach słabego oświetlenia, ze szczególnym uwzględnieniem widoczności twarzy.

Orkiestracja procesów:
model HDRNet i towarzysząca mu logika są koordynowane przez procesor Low Light Boost. Obejmuje to m.in.:

  1. Analiza sceny:
    niestandardowy kalkulator, który szacuje rzeczywistą jasność sceny na podstawie metadanych aparatu (czułość czujnika, czas ekspozycji itp.) i zawartości obrazu. Ta analiza określa poziom wzmocnienia.
  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. Łączenie:
    oryginalne klatki i klatki przetworzone przez HDRNet są łączone. Poziom mieszania jest dynamicznie kontrolowany przez kalkulator jasności sceny, co zapewnia płynne przejście między stanami wzmocnionym i niewzmocnionym.
low-light-boost-processor-diagram.png

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

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

Dzięki dwóm ścieżkom, sprzętowej i programowej, funkcja Low Light Boost zapewnia skalowalne rozwiązanie, które poprawia wydajność aparatu przy słabym oświetleniu w całym ekosystemie Androida. Deweloperzy powinni w miarę możliwości korzystać z trybu AE, a w razie potrzeby używać funkcji Google Low Light Boost jako niezawodnego rozwiązania zapasowego.

Wdrażanie doświetlania w aplikacji

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

Krok 1. Tryb AE wzmocnienia przy słabym oświetleniu

Dostępny na wybranych urządzeniach z Androidem 15 lub nowszym tryb LLB AE działa jako specjalny tryb automatycznej ekspozycji (AE).

1. Sprawdź dostępność

Najpierw sprawdź, czy aparat obsługuje tryb AE LLB.

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

2. Włączanie trybu

Jeśli jest obsługiwana, możesz włączyć tryb AE LLB 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. Monitorowanie stanu

Samo poproszenie o ten tryb nie oznacza, że obecnie „wzmacnia” on Twoje treści. System aktywuje wzmocnienie tylko wtedy, gdy scena jest rzeczywiście ciemna. Możesz skonfigurować obserwatora, aby aktualizować interfejs (np. wyświetlać ikonę księżyca) lub przekształcać go w 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 AE Low Light Boost znajdziesz tutaj.

Krok 2. Wzmocnienie przy słabym oświetleniu od Google

W przypadku urządzeń, które nie obsługują sprzętowego trybu AE, funkcja Google Low Light Boost stanowi skuteczne rozwiązanie zastępcze. Wykorzystuje LowLightBoostSession do przechwytywania i rozjaśniania strumienia.

1. Dodawanie zależności

Ta funkcja jest dostępna w ramach 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. Inicjowanie 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. Tworzenie sesji LLB

Google LLB przetwarza każdą klatkę, więc musisz przekazać wyświetlaną powierzchnię do LowLightBoostSession, a ona zwróci powierzchnię z zastosowanym rozjaśnieniem. W przypadku aplikacji Camera2 możesz dodać wynikową powierzchnię za pomocą metody CaptureRequest.Builder.addTarget(). W przypadku CameraX ten potok przetwarzania najlepiej pasuje do klasy CameraEffect, w której możesz zastosować efekt za pomocą klasy SurfaceProcessor i przekazać go z powrotem do podglądu za pomocą klasy 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. Przekazywanie metadanych

Aby algorytm działał, musi analizować stan automatycznej ekspozycji aparatu. Musisz przekazać wyniki przechwytywania z powrotem do sesji LLB. W CameraX można to zrobić, rozszerzając Preview.Builder za pomocą funkcji 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 wdrożenia po stronie klienta i sesji znajdziesz w  przewodniku Google Low Light Boost.

Następne kroki

Dzięki wdrożeniu 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, gotowym do wdrożenia kodzie, zapoznaj się z  aplikacją aparatu Jetpack w GitHubie. Implementuje zarówno tryb LLB AE, jak i Google LLB, dzięki czemu możesz wykorzystać go jako punkt odniesienia do własnej integracji. 

Autor:

Czytaj dalej