Nowości dotyczące produktów

Rozjaśnianie obrazu z kamery w czasie rzeczywistym dzięki funkcji Słabe oświetlenie

Czas czytania: 7 min
Wyświetl profil użytkownika Donovan McMurray
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 o wysokiej jakości. A 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 Słabe oświetlenie, 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 Słabe oświetlenie działa natychmiast na podglądzie na żywo i nagraniach wideo. Automatycznie dostosowuje stopień rozjaśnienia do dostępnego światła, dzięki czemu jest zoptymalizowana pod kątem każdego otoczenia.

Dzięki niedawnej aktualizacji funkcja Słabe oświetlenie umożliwia użytkownikom Instagrama ustawienie idealnego kadru, a dotychczasowe wdrożenie 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 zdjęć, a funkcja Słabe oświetlenie – zwiększenie użyteczności i interaktywności w ciemnym otoczeniu. Warto też pamiętać, że chociaż te funkcje bardzo dobrze ze sobą współpracują, można ich używać niezależnie. W niektórych przypadkach funkcja Słabe oświetlenie jest przydatna sama w sobie, gdy nie są potrzebne zdjęcia w trybie nocnym. Oto jak funkcja Słabe oświetlenie 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. Funkcja Słabe oświetlenie 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 Słabe oświetlenie 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 ciemnym otoczeniu.
  • Ulepszone interakcje: w przypadku aplikacji, które obejmują interakcje wideo na żywo (np. asystenci AI lub rozmowy wideo), funkcja Słabe oświetlenie zwiększa ilość informacji, które można dostrzec, dzięki czemu modele widzenia komputerowego 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 Słabe oświetlenie 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ę Słabe oświetlenie możesz wdrożyć na 2 sposoby, aby zapewnić najlepsze wrażenia na jak największej liczbie urządzeń:

  1. Tryb AE Słabe oświetlenie: 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. Słabe oświetlenie 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 możesz dotrzeć do większej liczby urządzeń z funkcją Słabe oświetlenie.

Tryb AE Słabe oświetlenie (sprzęt)

Mechanizm:
Ten tryb jest obsługiwany na urządzeniach z Androidem 15 i nowszymi wersjami. Wymaga też, aby producent OEM wdrożył 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, 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 powodować 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.

Słabe oświetlenie 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 Słabe oświetlenie. 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 wzmocnienia.
  2. Przetwarzanie HDRNet:
    stosuje model HDRNet do rozjaśniania klatki. Używany model jest dostosowany do scen przy 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 wzmocnionymi i niewzmocnionymi.
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że odzyskać szczegółów utraconych z powodu ekstremalnej ciemności na poziomie czujnika.

Dzięki oferowaniu ścieżek sprzętowych i programowych funkcja Słabe oświetlenie 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 priorytetowo traktować tryb AE i używać funkcji Słabe oświetlenie Google jako niezawodnego rozwiązania rezerwowego.

Wdrażanie funkcji Słabe oświetlenie w aplikacji

Przyjrzyjmy się teraz, jak wdrożyć obie oferty funkcji Słabe oświetlenie. Możesz wdrożyć te funkcje niezależnie od tego, czy w aplikacji używasz CameraX czy Camera2. Aby uzyskać najlepsze rezultaty, zalecamy wdrożenie zarówno kroku 1, jak i kroku 2.

Krok 1. Tryb AE Słabe oświetlenie

Dostępny na wybranych urządzeniach z Androidem 15 i nowszymi wersjami tryb AE Słabe oświetlenie działa jako specjalny tryb automatycznej ekspozycji (AE).

1. Sprawdź dostępność

Najpierw sprawdź, czy urządzenie z aparatem obsługuje tryb AE Słabe oświetlenie.

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

2. Włącz tryb

Jeśli jest obsługiwany, możesz włączyć tryb AE Słabe oświetlenie 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 „wzmocniony”. 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 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 dotyczący trybu AE Słabe oświetlenie znajdziesz tutaj.

Krok 2. Słabe oświetlenie Google

W przypadku urządzeń, które nie obsługują sprzętowego trybu AE, funkcja Słabe oświetlenie 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ę Słabe oświetlenie

Funkcja Słabe oświetlenie Google przetwarza każdą klatkę, dlatego musisz przekazać swój Surface wyświetlacza do LowLightBoostSession, a ona zwróci Ci Surface, na którym zastosowano rozjaśnienie. W przypadku aplikacji Camera2 możesz dodać wynikowy Surface 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 Słabe oświetlenie. W CameraX możesz 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 wdrażania klienta i sesji znajdziesz w przewodniku Słabe oświetlenie Google.

Następne kroki

Wdrożenie tych 2 opcji zapewni użytkownikom wyraźny obraz, niezawodne skanowanie i skuteczne interakcje niezależnie od warunków oświetleniowych.

Aby zobaczyć te funkcje w działaniu w kompletnym, gotowym do produkcji kodzie, zapoznaj się z aplikacją Jetpack Camera w GitHub. Implementuje ona zarówno tryb AE Słabe oświetlenie, jak i funkcję Słabe oświetlenie Google, co stanowi punkt odniesienia dla Twojej integracji. 

Autorzy:
Czytaj dalej