שימוש ב'עומק גולמי' באפליקציית Android

ה-Raw Depth API מספק נתוני עומק לתמונת מצלמה ברמת דיוק גבוהה יותר מנתוני Depth API מלאים, אבל לא תמיד מדובר בכל פיקסל. ניתן גם לבצע עיבוד נוסף של תמונות עומק גולמיות, יחד עם תמונות המהימנות התואמות שלהן, וכך לאפשר לאפליקציות להשתמש רק בנתוני עומק בעלי רמת דיוק גבוהה בתרחיש לדוגמה האישי שלהן.

אין לי מכשיר תואם

נתוני עומק גולמיים זמינים בכל המכשירים שתומכים ב-Depth API. ב-Raw Depth API, כמו ב-Depth API מלא, אין צורך בחיישן עומק נתמך של חומרה, כמו חיישן זמן טיסה (ToF). עם זאת, גם Raw Depth API וגם ה-Depth API המלא משתמשים בכל חיישני החומרה הנתמכים במכשיר.

Raw Depth API לעומת Full Depth API

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

בטבלה הבאה ממחישים את ההבדלים בין Raw Depth API לבין ה-Depth API המלא באמצעות תמונה של כיסא ושולחן במטבח.

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

תמונות מהימנות

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

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

עלות המחשוב

עלות המחשוב של Raw Depth API היא כמחצית מעלות המחשוב של Depth API המלא.

תרחישים לדוגמה

באמצעות Raw Depth API אפשר לקבל תמונות עומק שמספקות ייצוג מפורט יותר של הגיאומטריה של האובייקטים בסצנה. נתוני עומק גולמיים יכולים להיות שימושיים כשיוצרים חוויות AR שבהן נדרשים פרטים מדויקים יותר ומפורטים יותר למשימות של הבנת גיאומטריה. תרחישים לדוגמה כוללים:

  • שחזור בתלת ממד
  • מדידה
  • זיהוי צורות

דרישות מוקדמות

חשוב לוודא שאתם מבינים את המושגים הבסיסיים של AR ואיך להגדיר סשן ARCore לפני שממשיכים.

הפעלת העומק

בסשן ARCore חדש, בודקים אם המכשיר של המשתמש תומך ב'עומק'. חלק מהמכשירים שתואמים ל-ARCore לא תומכים ב-Depth API בגלל מגבלות כוח העיבוד. כדי לחסוך במשאבים, תכונת העומק מושבתת כברירת מחדל ב-ARCore. כדי שהאפליקציה תשתמש ב-Depth API, צריך להפעיל את מצב העומק.

Java

Config config = session.getConfig();

// Check whether the user's device supports Depth.
if (session.isDepthModeSupported(Config.DepthMode.AUTOMATIC)) {
  // Enable depth mode.
  config.setDepthMode(Config.DepthMode.AUTOMATIC);
}
session.configure(config);

Kotlin

if (session.isDepthModeSupported(Config.DepthMode.AUTOMATIC)) {
  session.configure(session.config.apply { depthMode = Config.DepthMode.AUTOMATIC })
}

אפשר לקבל את תמונות העומק והמהימנות העדכניות ביותר

קוראים לפונקציה frame.acquireRawDepthImage16Bits() כדי לקבל את תמונת העומק העדכנית ביותר. חלק מהפיקסלים של התמונות שמוחזרים דרך ה-Raw Depth API לא מכילים נתוני עומק, ולא כל מסגרת ARCore תכיל תמונת עומק גולמית חדשה. כדי לקבוע אם תמונת העומק הגולמית של המסגרת הנוכחית היא חדשה, צריך להשוות את חותמת הזמן שלה לחותמת הזמן של תמונת העומק הגולמית הקודמת. אם חותמות הזמן שונות, תמונת העומק הגולמית מבוססת על נתוני עומק חדשים. אחרת, תמונת העומק היא היטל מחדש של נתוני העומק הקודמים.

קוראים אל frame.acquireRawDepthConfidenceImage() כדי לקבל את תמונת הביטחון. אתם יכולים להשתמש בתמונה בר-הסמך כדי לבדוק את הדיוק של כל פיקסל עומק גולמי. תמונות סמך מוחזרות בפורמט Y8. כל פיקסל הוא מספר שלם לא חתום בגודל 8 ביט. 0 מציין את רמת הסמך הנמוכה ביותר, ואילו 255 מציין את רמת הסמך הגבוהה ביותר.

Java

// Use try-with-resources, so that images are released automatically.
try (
// Depth image is in uint16, at GPU aspect ratio, in native orientation.
Image rawDepth = frame.acquireRawDepthImage16Bits();
    // Confidence image is in uint8, matching the depth image size.
    Image rawDepthConfidence = frame.acquireRawDepthConfidenceImage(); ) {
  // Compare timestamps to determine whether depth is is based on new
  // depth data, or is a reprojection based on device movement.
  boolean thisFrameHasNewDepthData = frame.getTimestamp() == rawDepth.getTimestamp();
  if (thisFrameHasNewDepthData) {
    ByteBuffer depthData = rawDepth.getPlanes()[0].getBuffer();
    ByteBuffer confidenceData = rawDepthConfidence.getPlanes()[0].getBuffer();
    int width = rawDepth.getWidth();
    int height = rawDepth.getHeight();
    someReconstructionPipeline.integrateNewImage(depthData, confidenceData, width, height);
  }
} catch (NotYetAvailableException e) {
  // Depth image is not (yet) available.
}

Kotlin

try {
  // Depth image is in uint16, at GPU aspect ratio, in native orientation.
  frame.acquireRawDepthImage16Bits().use { rawDepth ->
    // Confidence image is in uint8, matching the depth image size.
    frame.acquireRawDepthConfidenceImage().use { rawDepthConfidence ->
      // Compare timestamps to determine whether depth is is based on new
      // depth data, or is a reprojection based on device movement.
      val thisFrameHasNewDepthData = frame.timestamp == rawDepth.timestamp
      if (thisFrameHasNewDepthData) {
        val depthData = rawDepth.planes[0].buffer
        val confidenceData = rawDepthConfidence.planes[0].buffer
        val width = rawDepth.width
        val height = rawDepth.height
        someReconstructionPipeline.integrateNewImage(
          depthData,
          confidenceData,
          width = width,
          height = height
        )
      }
    }
  }
} catch (e: NotYetAvailableException) {
  // Depth image is not (yet) available.
}

מה השלב הבא?

  • רוצים ללמוד איך לפתח אפליקציה משלכם עם עומק גולמי? תוכלו להיעזר בקוד Lab RAW.