Новости о продуктах

Как улучшить видеопоток с камеры в реальном времени с помощью функции "Усиление при слабом освещении"

Время на чтение: 7 минут
Посмотреть профиль пользователя Donovan McMurray
Donovan McMurray Developer Relations Engineer

Недавно мы рассказывали,  как Instagram позволяет пользователям делать потрясающие снимки при слабом освещении с помощью ночного режима. Эта функция идеально подходит для неподвижных изображений, когда есть время объединить несколько экспозиций для создания высококачественного статического снимка. Но что происходит между снимками? Пользователям нужно взаимодействовать с камерой не только в момент нажатия кнопки спуска затвора. Они также используют предварительный просмотр для создания сцены или сканирования QR-кодов.

Сегодня мы поговорим об усилении при слабом освещении – мощной функции, которая позволяет сделать видео с камеры ярче. В отличие от ночного режима, при котором нужно держать камеру неподвижно, функция "Улучшение при слабом освещении" работает мгновенно в режиме предварительного просмотра и при записи видео. Функция автоматически регулирует яркость в зависимости от доступного освещения, поэтому она оптимизирована для любых условий.

Благодаря недавнему обновлению пользователи Instagram могут выстроить идеальный кадр, а затем получить высококачественные фотографии при слабом освещении, которые они уже больше года делают в ночном режиме.

Почему важна яркость в реальном времени

Ночной режим улучшает качество итогового изображения, а усиление при слабом освещении повышает удобство использования и интерактивность в темноте. Ещё один важный фактор, который следует учитывать, заключается в том, что, хотя они очень хорошо работают вместе, вы можете использовать LLB и ночной режим независимо друг от друга, и вы увидите, что в некоторых из этих вариантов использования LLB имеет ценность сама по себе, когда фотографии в ночном режиме не нужны. Вот как это работает:

  • Улучшенное кадрирование и съемка. При слабом освещении на стандартном предпросмотре может быть ничего не видно. LLB делает видоискатель ярче, позволяя пользователям видеть, что они кадрируют, прежде чем нажать кнопку спуска затвора. Для этого вы можете использовать ночной режим, чтобы получить наилучшее качество фотографии при слабом освещении, или позволить LLB предоставить пользователю результат фотографии "что вы видите, то и получаете".
  • Надежное сканирование. QR-коды используются повсеместно, но сканировать их в темном ресторане или на парковке часто бывает неудобно. Благодаря значительно более яркому видеопотоку с камеры алгоритмы сканирования могут надежно обнаруживать и декодировать QR-коды даже в очень темных условиях.
  • Улучшенное взаимодействие. В приложениях, где используется видео в реальном времени, например в ИИ-помощниках или сервисах видеовызовов, LLB увеличивает количество воспринимаемой информации, чтобы у моделей компьютерного зрения было достаточно данных для работы.

Разница в Instagram

LLB_IG_demo_white_background.gif

Команда разработчиков приложения Instagram для Android постоянно работает над тем, чтобы пользователи могли делать снимки высокого качества. На примере выше видно, как сильно меняется изображение на Pixel 10 Pro при использовании функции "Улучшение при слабом освещении".

lowlight.png

Легко представить, насколько это удобно для пользователей. Если пользователи не видят, что они снимают, они могут отказаться от съемки. 

lowlight1.png

Выбор способа реализации

Чтобы обеспечить наилучшее качество на самых разных устройствах, можно реализовать усиление при слабом освещении двумя способами:

  1. Режим автоэкспозиции с усилением при слабом освещении. Это режим автоэкспозиции на аппаратном уровне. Он обеспечивает наивысшее качество и производительность, поскольку напрямую настраивает конвейер процессора обработки сигналов изображений (ISP). Всегда проверяйте это в первую очередь.
  2. Google Low Light Boost. Если устройство не поддерживает режим AE, вы можете использовать это программное решение, предоставляемое сервисами Google Play. Для этого используется постобработка видео с камеры. Поскольку это полностью программное решение, оно доступно на большем количестве устройств, что позволяет расширить охват.

Режим автоматической экспозиции с усилением при слабом освещении (аппаратный)

Механизм
Этот режим поддерживается на устройствах с Android 15 и более поздними версиями. Производитель оригинального оборудования должен реализовать поддержку в HAL (сейчас доступно на устройствах Pixel 10). Он напрямую интегрирован с процессором обработки сигналов изображений (ISP) камеры. Если вы установите для CaptureRequest.CONTROL_AE_MODE значение CameraMetadata.CONTROL_AE_MODE_ON_LOW_LIGHT_BOOST_BRIGHTNESS_PRIORITY, система камеры возьмет управление на себя.

Поведение.
HAL/ISP анализирует сцену и корректирует параметры датчика и обработки, часто увеличивая время экспозиции, чтобы сделать изображение ярче. Это позволяет получить кадры со значительно улучшенным соотношением "сигнал/шум", поскольку увеличенное время экспозиции, а не увеличение усиления цифрового датчика (ISO), позволяет датчику улавливать больше информации о свете.

Преимущество.
Потенциально более высокое качество изображения и энергоэффективность, поскольку используются выделенные аппаратные пути.

Недостаток.
В условиях низкой освещенности частота кадров может снижаться, поскольку датчику требуется больше времени, чтобы уловить свет. При очень слабом освещении частота кадров может снижаться до 10 кадров/с.

Усиление при слабом освещении от Google (ПО в сервисах Google Play)

Механизм
Это решение, распространяемое как необязательный модуль через сервисы Google Play, применяет постобработку к трансляции с камеры. В нем используется сложная технология улучшения изображения в реальном времени под названием HDRNet.

Google HDRNet
Эта модель глубокого обучения анализирует изображение с более низким разрешением, чтобы предсказать компактный набор параметров (двустороннюю сетку). Затем эта сетка используется для эффективного улучшения изображения в полном разрешении на графическом процессоре. Модель обучена осветлять и улучшать качество изображения в условиях низкой освещенности, уделяя особое внимание видимости лица.

Организация процесса.
Модель 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 Low Light Boost в качестве надежного резервного варианта.

Как реализовать усиление при слабом освещении в приложении

Теперь давайте посмотрим, как реализовать оба предложения LLB. Вы можете реализовать описанные ниже шаги независимо от того, используете ли вы в приложении CameraX или Camera2. Для достижения наилучших результатов рекомендуем выполнить оба шага.

Шаг 1. Режим автоэкспозиции для усиления при слабом освещении

Режим автоэкспозиции LLB AE доступен на некоторых устройствах с Android 15 и более поздними версиями ОС.

1. Проверить доступность

Сначала проверьте, поддерживает ли камера режим LLB AE.

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

2. Включите режим

Если поддерживается, вы можете включить режим LLB AE, используя объект CameraControl в 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. Отслеживание состояния

Если вы запросили режим, это не значит, что он сейчас работает. Система активирует усиление, только когда в кадре действительно темно. Вы можете настроить Observer, чтобы обновлять интерфейс (например, показывать значок луны), или преобразовать в Flow с помощью функции расширения asFlow().

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

Полное руководство по режиму автоэкспозиции "Усиление при слабом освещении" доступно  здесь.

Шаг 2. Усиление при слабом освещении от Google

Для устройств, которые не поддерживают аппаратный режим автоэкспозиции, Google Low Light Boost служит мощным резервным решением. Для перехвата и осветления потока используется 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 вы можете добавить полученный Surface с помощью CaptureRequest.Builder.addTarget(). Для 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 это можно сделать, расширив Preview.Builder с помощью 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)
    }
  }
)

Подробные инструкции по реализации клиента и сеанса можно найти в  руководстве по Google Low Light Boost.

Дальнейшие действия

Реализовав эти две функции, вы обеспечите пользователям возможность четко видеть, надежно сканировать и эффективно взаимодействовать независимо от условий освещения.

Чтобы увидеть эти функции в действии в полной, готовой к работе базе кода, ознакомьтесь с  приложением Jetpack Camera на GitHub. В нем реализованы как режим LLB AE, так и Google LLB, что дает вам ориентир для собственной интеграции. 

Автор:
Продолжить чтение