חדשות על מוצרים

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

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

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

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

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

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

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

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

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

LLB_IG_demo_white_background.gif

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

lowlight.png

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

lowlight1.png

בחירת ההטמעה

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

  1. מצב חשיפה אוטומטית (AE) עם הגברת התאורה החלשה: זהו מצב חשיפה אוטומטית בשכבת החומרה. הוא מציע את האיכות והביצועים הכי גבוהים כי הוא מכוונן את צינור העיבוד של מעבד אותות התמונה (ISP) באופן ישיר. תמיד כדאי לבדוק את זה קודם.
  2. שיפור התאורה החלשה של Google: אם המכשיר לא תומך במצב AE, אפשר להשתמש בפתרון הזה שמבוסס על תוכנה ומסופק על ידי Google Play Services. הוא מבצע עיבוד תמונה (Post Processing) בסטרימינג מהמצלמה כדי להבהיר אותו. הפתרון הזה מבוסס על תוכנה בלבד, ולכן הוא זמין במכשירים נוספים. כך תוכלו להגיע ליותר מכשירים עם LLB.

מצב AE לשיפור תמונות בתאורה חלשה (חומרה)

מנגנון:
המצב הזה נתמך במכשירים עם Android מגרסה 15 ואילך, ונדרש שהיצרן המקורי יישם את התמיכה ב-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 (תוכנה דרך 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 כגיבוי אמין.

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

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

אם המכשיר תומך בכך, אפשר להפעיל את מצב ה-AE של LLB באמצעות אובייקט 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 מעבדת כל פריים, ולכן צריך לתת לה את הפלטפורמה לתצוגה LowLightBoostSession, והיא מחזירה פלטפורמה עם ההבהרה. באפליקציות 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 Camera App ב-GitHub. הוא מיישם גם מצב LLB AE וגם Google LLB, כך שתוכלו להשתמש בו כהפניה לשילוב משלכם. 

נכתב על ידי:

להמשך הקריאה