دليل المطوّر حول الصور المعزّزة لنظام التشغيل Android NDK

تعرَّف على كيفية استخدام ميزة "الصور المعزَّزة" في تطبيقاتك.

المتطلبات الأساسية

قبل المتابعة، تأكد من فهم مفاهيم الواقع المعزّز الأساسية وكيفية ضبط جلسة ARCore.

إنشاء قاعدة بيانات للصور

أنشئ ArAugmentedImageDatabase لتخزين الصور المرجعية. هناك طريقتان:

  • إنشاء قاعدة بيانات فارغة
ArAugmentedImageDatabase* ar_augmented_image_database = NULL;
ArAugmentedImageDatabase_create(ar_session, &ar_augmented_image_database);
  • القراءة من ملف قاعدة بيانات صورة يُرجى الاطّلاع على [AugmentedImage C نموذج تطبيق] لـ util::LoadFileFromAssetManager.
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 نقاطًا خاصة بصورة الكاميرا لمطابقة تلك النقاط في قاعدة بيانات الصور.

العثور على صور محسّنة في جلسة الواقع المعزّز

للحصول على الصور المطابقة، يمكنك إجراء استطلاع للحصول على ArAugmentedImage المعدَّلة في حلقة تعديل الإطار.

// 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