Nowości dotyczące produktów

Rozjaśnianie obrazu z kamery w czasie rzeczywistym dzięki funkcji doświetlania

7 min czytania
Wyświetl profil Donovana McMurraya
Donovan McMurray Inżynier ds. relacji z deweloperami

Niedawno informowaliśmy jak Instagram umożliwił użytkownikom robienie wspaniałych zdjęć przy słabym oświetleniu za pomocą trybu nocnego. Ta funkcja jest idealna do zdjęć statycznych, w przypadku których jest czas na połączenie kilku ekspozycji w celu utworzenia statycznego zdjęcia wysokiej jakości. Ale co z momentami, które zdarzają 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 Low Light Boost (LLB), która rozjaśnia strumienie z kamery w czasie rzeczywistym. W przeciwieństwie do trybu nocnego, który wymaga dłuższego czasu naświetlania, funkcja doświetlania działa natychmiast na podglądzie na żywo i nagraniach wideo. LLB automatycznie dostosowuje stopień rozjaśnienia do dostępnego światła, dzięki czemu jest zoptymalizowana pod kątem każdego środowiska.

Dzięki niedawnej aktualizacji funkcja LLB umożliwia użytkownikom Instagrama ustawienie idealnego ujęcia, a następnie wykorzystanie istniejącej implementacji trybu nocnego, aby uzyskać zdjęcia w słabym oświetleniu o takiej samej wysokiej jakości, z jakiej 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 jest przeznaczona do użyteczności i interaktywności w ciemnym otoczeniu. Kolejnym ważnym czynnikiem jest to, że chociaż te funkcje bardzo dobrze ze sobą współpracują, można ich używać niezależnie. W niektórych przypadkach funkcja doświetlania jest przydatna sama w sobie, gdy nie są potrzebne zdjęcia w trybie nocnym. Oto jak funkcja doświetlania poprawia wygodę użytkowników:

  • Lepsze kadrowanie i rejestrowanie: w słabo oświetlonych scenach standardowy podgląd z kamery może być całkowicie czarny. Funkcja doświetlania 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ęć w słabym oświetleniu, lub pozwolić funkcji doświetlania 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łabym oświetleniu.
  • Ulepszone interakcje: w przypadku aplikacji obejmujących interakcje wideo na żywo (takich jak asystenci AI czy rozmowy wideo) funkcja doświetlania zwiększa ilość informacji, które można dostrzec, dzięki czemu modele widzenia komputerowego mają wystarczającą ilość 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 doświetlania 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 można zaimplementować na 2 sposoby, aby zapewnić najlepsze wrażenia na jak największej liczbie urządzeń:

  1. Tryb doświetlania AE: 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. Funkcja doświetlania Google: jeśli urządzenie nie obsługuje trybu AE, 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 ta implementacja pomaga dotrzeć do większej liczby urządzeń z funkcją doświetlania.

Tryb doświetlania AE (sprzęt)

Mechanizm:
Ten tryb jest obsługiwany na urządzeniach z Androidem 15 i nowszymi wersjami. Wymaga on, aby producent OEM zaimplementował obsługę w HAL (obecnie dostępną 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, kontrolę przejmie system aparatu.

Zachowanie:
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 spowodować uzyskanie klatek 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.

Funkcja doświetlania 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.

Google HDRNet:
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. 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 do rozjaśniania klatki. 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 i przetworzone przez HDRNet klatki są mieszane. Stopień mieszania jest dynamicznie kontrolowany przez kalkulator jasności sceny, co zapewnia płynne przejście między stanami doświetlania i bez doświetlania.
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 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 AE i używać funkcji doświetlania Google jako niezawodnego rozwiązania rezerwowego.

Implementowanie funkcji doświetlania w aplikacji

Przyjrzyjmy się teraz, jak zaimplementować obie oferty funkcji doświetlania. Możesz zaimplementować te funkcje 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 doświetlania AE

Dostępny na wybranych urządzeniach z Androidem 15 i nowszymi wersjami tryb doświetlania AE działa jako określony tryb automatycznej ekspozycji (AE).

1. Sprawdź dostępność

Najpierw sprawdź, czy urządzenie z aparatem obsługuje tryb doświetlania AE.

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

2. Włącz tryb

Jeśli jest obsługiwany, możesz włączyć tryb doświetlania AE 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 doświetlania AE znajdziesz tutaj.

Krok 2. Funkcja doświetlania Google

W przypadku urządzeń, które nie obsługują sprzętowego trybu AE, funkcja doświetlania Google działa jako niezawodne rozwiązanie rezerwowe. Używa ona LowLightBoostSession do przechwytywania i rozjaśniania strumienia.

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ę doświetlania

Funkcja doświetlania Google przetwarza każdą klatkę, dlatego musisz przekazać powierzchnię wyświetlacza do LowLightBoostSession, a ona zwróci powierzchnię, na której zastosowano rozjaśnienie. 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 doświetlania. 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 funkcji doświetlania 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 kodzie gotowym do użycia w środowisku produkcyjnym, zapoznaj się z aplikacją Jetpack Camera w GitHub. Implementuje ona zarówno tryb doświetlania AE, jak i funkcję doświetlania Google, co stanowi odniesienie do własnej integracji. 

Autor:
Czytaj dalej