產品最新消息

使用低光源強化功能,調亮即時攝影機畫面

閱讀時間:7 分鐘
查看 Donovan McMurray 的個人資料
Donovan McMurray 開發人員關係工程師

我們最近分享了  Instagram 如何讓使用者透過夜間模式拍攝出色的低光源相片。這項功能非常適合用於靜態影像,因為有時間結合多重曝光,建立高品質的靜態拍攝。但如果想記錄相片之間的時刻,該怎麼辦?使用者與相機的互動不應僅限於按下快門按鈕。此外,他們也會使用預覽畫面來構圖或掃描 QR code。

今天,我們要深入探討低光源增強 (LLB),這項強大功能可提高即時攝影機串流影像的亮度。與夜間模式不同,低光源強化功能會立即在即時預覽和影片錄製中生效,不需等待拍攝完成。LLB 會根據可用光線自動調整亮度,因此在任何環境下都能呈現最佳效果。

在最近一次更新中,LLB 讓 Instagram 使用者能拍出完美相片,而現有的夜間模式實作則能產生相同的高畫質低光源相片,讓使用者一年多來都能享受這項功能。

即時亮度為何重要

夜間模式旨在提升最終影像品質,而低光源強化功能則著重於在昏暗環境中的實用性和互動性。另一個需要考量的重要因素是,雖然低光源模式和夜間模式可以搭配使用,但也可以單獨使用。在某些情況下,即使不需要夜間模式相片,低光源模式本身也很有價值。以下說明 LLB 如何提升使用者體驗:

  • 更出色的取景和拍攝效果:在昏暗場景中,標準相機預覽畫面可能會一片漆黑。LLB 會調亮觀景窗,讓使用者在按下快門按鈕前,能實際看到取景畫面。在這種情況下,你可以使用夜間模式,在低光源環境下拍出最佳相片,也可以讓 LLB 為使用者提供「所見即所得」的相片。
  • 可靠的掃描功能:QR code 隨處可見,但在昏暗的餐廳或室內停車場掃描時,往往會遇到困難。攝影機畫面亮度大幅提升後,即使在非常昏暗的環境中,掃描演算法也能可靠地偵測及解碼 QR code。
  • 強化互動:如果應用程式涉及即時影像互動 (例如 AI 助理或視訊通話),LLB 可增加可感知資訊量,確保電腦視覺模型有足夠的資料可供處理

Instagram 差異

LLB_IG_demo_white_background.gif

Android Instagram 應用程式的工程團隊一直努力不懈,致力為使用者提供最先進的相機體驗。從上方的範例中,你可以看到 LLB 在 Pixel 10 Pro 上的效果有多明顯。

lowlight.png

不難想像這對使用者體驗造成的影響。如果使用者無法看到自己拍攝的內容,就更有可能放棄拍攝。

lowlight1.png

選擇導入方式

您可以透過兩種方式導入低光源增強功能,在各種裝置上提供最佳體驗:

  1. 低光源增強 AE 模式:這是硬體層自動曝光模式。由於直接微調影像訊號處理器 (ISP) 管道,因此可提供最高品質和效能。請務必先檢查這一點。
  2. Google 低光源提升:如果裝置不支援 AE 模式,可以改用 Google Play 服務提供的軟體解決方案。系統會對攝影機串流影像進行後置處理,提高亮度。由於這項解決方案完全以軟體形式提供,因此適用於更多裝置,可協助您透過 LLB 觸及更多裝置。

低光源增強 AE 模式 (硬體)

機制:
搭載 Android 15 以上版本的裝置支援此模式,且原始設備製造商 (OEM) 必須在 HAL 中實作支援 (目前適用於 Pixel 10 裝置)。直接與相機的影像訊號處理器 (ISP) 整合。如果將 CaptureRequest.CONTROL_AE_MODE 設為 CameraMetadata.CONTROL_AE_MODE_ON_LOW_LIGHT_BOOST_BRIGHTNESS_PRIORITY,相機系統就會接管控制權。

行為:
HAL/ISP 會分析場景並調整感應器和處理參數,通常包括增加曝光時間,以提高圖片亮度。由於曝光時間延長,感應器可擷取更多光線資訊,因此不必提高數位感應器增益 (ISO),就能大幅提升影格的訊噪比 (SNR)。

優點:
利用專屬硬體路徑,可能提升影像品質和能源效率。

缺點:
在極暗環境下,感應器需要更多時間捕捉光線,因此影格率可能會降低。在極低光源環境下,影格率最低可降至 10 FPS。

Google 低光源增強 (透過 Google Play 服務提供的軟體)

機制:
這項解決方案會透過 Google Play 服務以選用模組的形式發布,並對攝影機串流影像套用後置處理。這項功能採用名為 HDRNet 的精密即時影像強化技術。

Google HDRNet:
這個深度學習模型會以較低解析度分析圖片,預測一組精簡的參數 (雙邊網格),接著,這個網格會引導 GPU 對全解析度圖片進行高效、空間變化的強化。這個模型經過訓練,可在低光源環境下調亮及提升影像品質,並著重於臉部清晰度。

程序自動化調度管理:
HDRNet 模型和相關邏輯由低光源增強處理器自動調度管理。包括:

  1. 場景分析:
    自訂計算工具,可使用相機中繼資料 (感應器感光度、曝光時間等) 和圖片內容,估算真實場景亮度。這項分析會決定提升等級。
  2. HDRNet 處理:
    套用 HDRNet 模型,提高畫面亮度。使用的模型經過調整,適用於低光源場景,並針對即時效能進行最佳化。
  3. 混合:
    原始和 HDRNet 處理過的影格會混合。場景亮度計算工具會動態控制混合程度,確保強化和未強化狀態之間的轉換流暢。
low-light-boost-processor-diagram.png

優點:
支援更多裝置 (目前支援 Samsung S22 Ultra、S23 Ultra、S24 Ultra、S25 Ultra,以及 Pixel 6 至 Pixel 9),不需特定 HAL 支援。由於這是後製效果,因此可維持相機的影格率。

缺點:
由於這是後製處理方法,因此品質會受限於感應器提供的影格資訊。如果感應器偵測到極度黑暗,則無法復原遺失的細節。

低光源強化功能提供硬體和軟體兩種途徑,可做為可擴充的解決方案,提升整個 Android 生態系統的低光源相機效能。開發人員應優先使用 AE 模式 (如有),並將 Google 低光源提升功能做為可靠的備用方案。

在應用程式中導入低光源增強功能

接著,我們來看看如何導入這兩種 LLB 方案。無論您在應用程式中使用 CameraX 或 Camera2,都可以實作下列步驟。為獲得最佳效果,建議您同時實作步驟 1 和步驟 2。

步驟 1:低光源增強 AE 模式

LLB AE 模式適用於搭載 Android 15 以上版本的特定裝置,是一種特定的自動曝光 (AE) 模式。

1. 檢查供應情形

首先,請確認相機裝置是否支援 LLB AE 模式。

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

2. 啟用模式

如果支援,您可以使用 CameraX 的 CameraControl 物件啟用 LLB AE 模式。

// 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. 監控狀態

即使你要求啟用該模式,也不代表系統目前正在「加速」。只有在場景確實昏暗時,系統才會啟用增強功能。您可以設定 Observer 來更新 UI (例如顯示月亮圖示),或使用擴充功能函式 asFlow() 轉換為 Flow。

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

如需低光源強化自動曝光模式的完整指南,請參閱 這篇文章。

步驟 2:Google 低光源增強

如果裝置不支援硬體 AE 模式,Google 低光源增強功能可做為強大的備用方案。它會使用 LowLightBoostSession 攔截並調亮串流。

1. 新增依附元件

這項功能是透過 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. 初始化用戶端

啟動相機前,請使用 LowLightBoostClient 確認模組已安裝,且裝置支援該模組。

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. 建立 LLB 工作階段

Google LLB 會處理每個影格,因此您必須將顯示 Surface 提供給 LowLightBoostSession,系統會傳回已套用亮度調整的 Surface。如果是 Camera2 應用程式,您可以使用 CaptureRequest.Builder.addTarget() 新增產生的 Surface。如果是 CameraX,這個處理管道最適合與 CameraEffect 類別搭配使用,您可以使用 SurfaceProcessor 套用效果,並使用 SurfaceProvider 將效果提供給預覽畫面,如這段程式碼所示。

// 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. 傳入中繼資料

演算法必須分析相機的自動曝光狀態,才能正常運作。您必須將擷取結果傳回 LLB 工作階段。在 CameraX 中,您可以使用 Camera2Interop.Extender.setSessionCaptureCallback() 擴充 Preview.Builder,即可完成這項操作。

Camera2Interop.Extender(previewBuilder).setSessionCaptureCallback(
  object : CameraCaptureSession.CaptureCallback() {
    override fun onCaptureCompleted(
      session: CameraCaptureSession,
      request: CaptureRequest,
      result: TotalCaptureResult
    ) {
      super.onCaptureCompleted(session, request, result)
      llbSession?.processCaptureResult(result)
    }
  }
)

如需用戶端和工作階段的詳細實作步驟,請參閱  Google 低光源強化指南。

後續步驟

只要實作這兩種選項,無論光線條件如何,使用者都能清楚看見、可靠掃描,並有效互動。

如要查看這些功能在可部署於正式環境的完整程式碼集中如何運作,請前往 GitHub 參閱  Jetpack Camera 應用程式。這項工具會實作 LLB AE 模式和 Google LLB,可做為您整合時的參考。

作者:
繼續閱讀