חדשות על המוצר

איך להבהיר את פיד המצלמה בזמן אמת באמצעות התכונה "שיפור בתאורה חלשה"

משך הקריאה: 7 דקות
הצגת הפרופיל של Donovan McMurray
Donovan McMurray מהנדס קשרי מפתחים

לאחרונה שיתפנו איך אינסטגרם מאפשרת למשתמשים לצלם תמונות מדהימות בתאורה חלשה באמצעות מצב לילה. התכונה הזו מושלמת לתמונות סטילס, שבהן יש זמן לשלב כמה חשיפות כדי ליצור תמונה סטטית באיכות גבוהה. אבל מה עם הרגעים שקורים בין התמונות? המשתמשים צריכים לבצע פעולות במצלמה, ולא רק ללחוץ על כפתור הצילום. הם גם משתמשים בתצוגה המקדימה כדי להרכיב את הסצנה או לסרוק קודי QR.

היום נתעמק בשיפור איכות התאורה (LLB), תכונה מתקדמת שנועדה להבהיר את הסטרימינג מהמצלמה בזמן אמת. בניגוד למצב לילה, שבו צריך להחזיק את המכשיר בלי לזוז בזמן הצילום, התכונה "שיפור התאורה" פועלת באופן מיידי בתצוגה המקדימה בזמן אמת ובהקלטות הווידאו. התכונה 'תאורה חלשה' מבצעת כוונון אוטומטי של מידת ההבהרה הנדרשת בהתאם לאור הזמין, כך שהיא מותאמת לכל סביבה.

בעדכון האחרון, LLB מאפשר למשתמשי אינסטגרם להגדיר את הצילום המושלם, ואז ההטמעה הקיימת של מצב הלילה מניבה את אותן תמונות באיכות גבוהה בתאורה חלשה שהמשתמשים נהנים מהן כבר יותר משנה.

למה חשוב להשתמש ב"בהירות בזמן אמת"

מצב לילה נועד לשפר את איכות התמונה הסופית, ואילו "שיפור בתאורה חלשה" נועד לשפר את השימושיות והאינטראקטיביות בסביבות חשוכות. עוד גורם חשוב שצריך להביא בחשבון הוא שלמרות שהם עובדים טוב מאוד ביחד, אפשר להשתמש ב-LLB ובמצב לילה בנפרד. בחלק מהמקרים האלה, ל-LLB יש ערך בפני עצמו כשלא צריך תמונות במצב לילה. כך LLB משפר את חוויית המשתמש:

  • פריים וצילום משופרים: בסצנות עם תאורה חלשה, התצוגה המקדימה הרגילה של המצלמה יכולה להיות חשוכה לחלוטין. התכונה הזו מבהירה את תצוגת הצילום, כך שהמשתמשים יכולים לראות מה הם מצלמים לפני שהם לוחצים על כפתור הצילום. כדי לצלם תמונות איכותיות בתאורה חלשה, אתם יכולים להשתמש במצב לילה או לתת ל-LLB להציג למשתמש את התוצאה "מה שרואים זה מה שמקבלים".
  • סריקה אמינה: קודי QR נמצאים בכל מקום, אבל סריקה שלהם במסעדה חשוכה או בחניון היא לעיתים קרובות מתסכלת. כשהפיד של המצלמה בהיר יותר, אלגוריתמי הסריקה יכולים לזהות ולפענח קודי QR בצורה אמינה גם בסביבות חשוכות מאוד.
  • אינטראקציות משופרות: באפליקציות שכוללות אינטראקציות של וידאו בשידור חי (כמו עוזרים אישיים מבוססי-AI או שיחות וידאו), התכונה "שיפור התאורה" מגדילה את כמות המידע שניתן לזהות, וכך מבטיחה שלמודלים של ראייה ממוחשבת יהיו מספיק נתונים לעבוד איתם.

ההבדל באינסטגרם

LLB_IG_demo_white_background.gif

צוות ההנדסה של אפליקציית אינסטגרם ל-Android עובד קשה כדי לספק למשתמשים חוויית צילום מתקדמת. בדוגמה שלמעלה אפשר לראות את ההבדל ש-LLB יוצר ב-Pixel 10 Pro. 

lowlight.png

קל לדמיין את ההבדל שזה יוצר בחוויית המשתמש. אם המשתמשים לא יכולים לראות את מה שהם מצלמים, יש סיכוי גבוה יותר שהם ינטשו את הצילום. 

lowlight1.png

בחירת ההטמעה

יש שתי דרכים להטמיע את התכונה "שיפור איכות התאורה" כדי לספק את חוויית השימוש הטובה ביותר במגוון רחב של מכשירים:

  1. מצב חשיפה אוטומטית לשיפור התאורה החלשה: זהו מצב חשיפה אוטומטית בשכבת החומרה. הוא מציע את האיכות והביצועים הטובים ביותר כי הוא מכוונן ישירות את צינור עיבוד הנתונים של מעבד האותות בתמונות (ISP). תמיד כדאי לבדוק קודם את זה.
  2. שיפור התאורה של Google: אם המכשיר לא תומך במצב החשיפה האוטומטית, אתם יכולים להשתמש בפתרון הזה שמבוסס על תוכנה ומסופק על ידי Google Play Services. התכונה הזו מפעילה עיבוד בדיעבד על הסטרימינג מהמצלמה כדי להבהיר אותו. הפתרון הזה מבוסס כולו על תוכנה, ולכן הוא זמין ביותר מכשירים. כך תוכלו להגיע ליותר מכשירים עם 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 מנתח את הסצנה ומתאים את הפרמטרים של החיישן והעיבוד, לעיתים קרובות כולל הגדלת זמן החשיפה, כדי להבהיר את התמונה. כך אפשר לקבל פריימים עם יחס אות לרעש (SNR) משופר באופן משמעותי, כי זמן החשיפה המורחב, ולא עלייה בהגבר החיישן הדיגיטלי (ISO), מאפשר לחיישן לתעד יותר מידע על האור.

יתרון:
איכות התמונה עשויה להיות טובה יותר וצריכת החשמל יעילה יותר, כי נעשה שימוש בנתיבי חומרה ייעודיים.

החיסרון:
יכול להיות שקצב הפריימים יהיה נמוך יותר בתנאי תאורה חשוכים מאוד, כי החיישן צריך יותר זמן כדי לקלוט אור. בתנאי תאורה חלשים מאוד, קצב הפריימים יכול לרדת עד ל-10 FPS.

‫Google Low Light Boost (תוכנה דרך Google Play Services)

המנגנון:
הפתרון הזה, שמופץ כמודול אופציונלי דרך Google Play Services, מבצע עיבוד לאחר הצילום של הסטרימינג מהמצלמה. היא משתמשת בטכנולוגיה מתוחכמת לשיפור תמונות בזמן אמת שנקראת 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 Low Light Boost כגיבוי חזק.

איך מטמיעים את התכונה "הגברת התאורה" באפליקציה

עכשיו נראה איך מטמיעים את שתי האפשרויות של 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. הפעלת המצב

אם יש תמיכה, אפשר להפעיל את מצב 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)
  }
}

 כאן אפשר לקרוא את המדריך המלא על מצב AE לשיפור התאורה.

שלב 2: שיפור התאורה של Google

במכשירים שלא תומכים במצב AE בחומרה, התכונה "שיפור התאורה של Google" משמשת כגיבוי יעיל. הוא משתמש ב-LowLightBoostSession כדי ליירט את השידור ולהבהיר אותו.

1. הוספת יחסי תלות

התכונה הזו מסופקת דרך Google Play Services.

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 בנושא שיפור איכות הווידאו בתאורה חלשה מפורטים השלבים להטמעה בצד הלקוח ובסשן.

השלבים הבאים

הטמעה של שתי האפשרויות האלה תאפשר למשתמשים לראות בבירור, לסרוק בצורה אמינה ולבצע פעולות ביעילות, בלי קשר לתנאי התאורה.

כדי לראות את התכונות האלה בפעולה בבסיס קוד מלא שמוכן לייצור, כדאי לעיין ב אפליקציית המצלמה של Jetpack ב-GitHub. הוא מטמיע גם את מצב LLB AE וגם את Google LLB, ומספק לכם חומר עזר לשילוב שלכם. 

כותב/ת המסמך:
להמשך קריאה