מדריך למפתחים של תמונות משופרות ל-Android NDK

כך תוכלו להשתמש בתמונות משופרות באפליקציות שלכם.

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

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

יצירת מסד נתונים של תמונות

יוצרים ArAugmentedImageDatabase כדי לאחסן תמונות הפניה. יש שתי דרכים לעשות זאת:

  • יצירת מסד נתונים ריק
ArAugmentedImageDatabase* ar_augmented_image_database = NULL;
ArAugmentedImageDatabase_create(ar_session, &ar_augmented_image_database);
std::string database_buffer;
util::LoadFileFromAssetManager(asset_manager_, "sample_database.imgdb",
                               &database_buffer);
uint8_t* raw_buffer = reinterpret_cast<uint8_t*>(&database_buffer.front());

ArAugmentedImageDatabase* ar_augmented_image_database = NULL;
const ArStatus status = ArAugmentedImageDatabase_deserialize(
    ar_session, raw_buffer, database_buffer.size(),
    &ar_augmented_image_database);

ניתן ליצור קבצים של מסדי נתונים באמצעות כלי התמונות או על ידי קריאה ל-ArAugmentedImageDatabase_serialize().

הוספת תמונות למסד הנתונים

השלב הזה הוא אופציונלי אם תמונות העזר הרצויות כבר נטענו מקובץ מסד הנתונים. כדי להוסיף תמונה בזמן ריצה, יש להפעיל את ArAugmentedImageDatabase_addImage() כפי שמוצג למטה. באפליקציה לדוגמה augmented_image_c תוכלו לראות פונקציות במרחב השמות של util.

int32_t width, height, stride, index;
uint8_t* image_pixel_buffer = nullptr;
constexpr const char kSampleImageName[] = "default.jpg";
bool load_image_result = util::LoadImageFromAssetManager(
    kSampleImageName, &width, &height, &stride, &image_pixel_buffer);

uint8_t* grayscale_buffer = nullptr;
util::ConvertRgbaToGrayscale(image_pixel_buffer, width, height, stride,
                             &grayscale_buffer);

int32_t grayscale_stride = stride / 4;
const ArStatus status = ArAugmentedImageDatabase_addImage(
    ar_session_, ar_augmented_image_database, kSampleImageName,
    grayscale_buffer, width, height, grayscale_stride, &index);

// If the physical size of the image is known, you can instead use
//     ArStatus ArAugmentedImageDatabase_addImageWithPhysicalSize
// This will improve the initial detection speed. ARCore will still actively
// estimate the physical size of the image as it is viewed from multiple
// viewpoints.

delete[] image_pixel_buffer;
delete[] grayscale_buffer;

הערכים index ו-name משמשים מאוחר יותר לזיהוי תמונת העזר שזוהתה.

הפעלת מעקב אחר תמונות

כדי להגדיר את סשן ARCore למעקב אחרי תמונות, צריך לרשום את מסד הנתונים של התמונות:

ArConfig_setAugmentedImageDatabase(ar_session_, ar_config,
                                   ar_augmented_image_database);
const ArStatus status = ArSession_configure(ar_session_, ar_config);

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

חיפוש תמונות מורחבות בסשן AR

כדי לקבל את התמונות התואמות, צריך לבצע סקר לגבי ArAugmentedImages מעודכנים בלולאת עדכון המסגרת.

// Update loop, in onDrawFrame
ArTrackableList* updated_image_list = nullptr;
ArTrackableList_create(ar_session_, &updated_image_list);
ArFrame_getUpdatedTrackables(
    ar_session_, ar_frame_, AR_TRACKABLE_AUGMENTED_IMAGE, updated_image_list);

int32_t image_list_size;
ArTrackableList_getSize(ar_session_, updated_image_list, &image_list_size);

for (int i = 0; i < image_list_size; ++i) {
  ArTrackable* ar_trackable = nullptr;
  ArTrackableList_acquireItem(ar_session_, updated_image_list, i,
                              &ar_trackable);
  ArAugmentedImage* image = ArAsAugmentedImage(ar_trackable);

  ArTrackingState tracking_state;
  ArTrackable_getTrackingState(ar_session_, ar_trackable, &tracking_state);

  int image_index;
  ArAugmentedImage_getIndex(ar_session_, image, &image_index);

  if (tracking_state == AR_TRACKING_STATE_TRACKING) {
    util::ScopedArPose scopedArPose(ar_session_);
    ArAugmentedImage_getCenterPose(ar_session_, image,
                                   scopedArPose.GetArPose());

    ArAnchor* image_anchor = nullptr;
    const ArStatus status = ArTrackable_acquireNewAnchor(
        ar_session_, ar_trackable, scopedArPose.GetArPose(), &image_anchor);

    // For example, you can now render content at the image anchor, choosing
    // content based on the image index (or name).
  }
}

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

כשמערכת ARCore מזהה תמונה מוגדלת, נוצר ערך Trackable לתמונה המוגדלת הזו, והערך ArTrackingState מוגדר ל-TRACKING ול-ArAugmentedImageTrackingMethod לערך FULL_TRACKING. כשהתמונה שבמעקב יוצאת מתצוגת המצלמה, ב-ARCore ממשיך להגדיר את ArTrackingState ל-TRACKING, אבל משנה את הערך ArAugmentedImageTrackingMethod ל-LAST_KNOWN_POSE ועדיין מספק את הכיוון והמיקום של התמונה.

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

  • תמונות מתוקנות. ברוב תרחישי השימוש בתמונות שמתוקנות במיקום (כלומר, לא צפויות לזוז) אפשר פשוט להשתמש בפונקציה ArTrackingState כדי לקבוע אם התמונה זוהתה ואם המיקום שלה ידוע. אפשר להתעלם מ-ArAugmentedImageTrackingMethod.

  • תמונות זזות. אם האפליקציה שלכם צריכה לעקוב אחרי תמונה נעה, כדאי להשתמש ב-ArTrackingState וב-ArAugmentedImageTrackingMethod כדי לקבוע אם התמונה זוהתה ואם המיקום שלה ידוע.

תרחיש לדוגמה תמונה מתוקנת התמונה זזה
דוגמה פוסטר שתלוי על קיר פרסומת לצד אוטובוס
התנוחה יכולה להיחשב תקפה
כאשר
ArTrackingState == TRACKING ArTrackingState == TRACKING
ו-
ArAugmentedImageTrackingMethod == FULL_TRACKING