دليل رصد العناصر في نظام التشغيل iOS

تتيح لك مهمة كشف الكائنات اكتشاف وجود وفئات الكائنات. على سبيل المثال، يمكن لجهاز الكشف عن الكلاب تحديد موقع الكلاب في . توضّح لك هذه التعليمات كيفية استخدام مهمة "أداة رصد العناصر" في نظام التشغيل iOS. تشير رسالة الأشكال البيانية يتوفّر نموذج التعليمات البرمجية الموضّح في هذه التعليمات على GitHub.

يمكنك رؤية هذه المهمة وهي قيد التنفيذ من خلال عرض الويب هذا تجريبي. بالنسبة مزيد من المعلومات حول الإمكانات والنماذج وخيارات التهيئة هذه المهمة، فراجع نظرة عامة:

مثال على الرمز البرمجي

رمز مثال "مهام MediaPipe" هو تنفيذ أساسي لكائن تطبيق الرصد لنظام التشغيل iOS. يستخدم المثال الكاميرا الموجودة على جهاز iOS فعلي من أجل ترصد العناصر بشكل مستمر، ويمكنها أيضًا استخدام الصور والفيديوهات من الجهاز. المعرض لاكتشاف الكائنات بشكل ثابت.

يمكنك استخدام التطبيق كنقطة بداية لتطبيق iOS، أو الرجوع إليه عند تعديل تطبيق حالي. تتم استضافة نموذج الرمز البرمجي لأداة كشف الكائنات على GitHub.

تنزيل الرمز

توضّح لك التعليمات التالية كيفية إنشاء نسخة على الجهاز من هذا المثال. باستخدام أداة سطر الأوامر git.

لتنزيل نموذج الرمز:

  1. استنساخ مستودع git باستخدام الأمر التالي:

    git clone https://github.com/google-ai-edge/mediapipe-samples
    
  2. يمكنك اختياريًا ضبط مثيل git لاستخدام عملية دفع متفرقة، وبالتالي ملفات تطبيق Object Detector فقط:

    cd mediapipe
    git sparse-checkout init --cone
    git sparse-checkout set examples/object_detection/ios/
    

بعد إنشاء نسخة محلية من نموذج الرمز، يمكنك تثبيت مكتبة مهام MediaPipe، افتح المشروع باستخدام Xcode وشغِّل التطبيق. بالنسبة التعليمات، راجِع دليل إعداد iOS.

المكوّنات الرئيسية

تحتوي الملفات التالية على التعليمات البرمجية المهمة لمثال أداة كشف الكائنات app:

  • ObjectDetectorService.swift: يؤدي هذا الإعداد إلى إعداد أداة الرصد ومعالجة اختيار النموذج وإجراء الاستنتاج على بيانات الإدخال.
  • CameraViewController.swift: لتنفيذ واجهة المستخدم لوضع إدخال خلاصة الكاميرا المباشرة وعرض مرئيات نتائج الاكتشاف.
  • MediaLibraryViewController.swift: لتنفيذ واجهة المستخدم لوضع إدخال الصور الثابتة وملفات الفيديو تصور نتائج الكشف.

ضبط إعدادات الجهاز

يصف هذا القسم الخطوات الرئيسية لإعداد بيئة التطوير مشاريع الرموز البرمجية لاستخدام أداة رصد الكائنات. للحصول على معلومات عامة حول إعداد بيئة تطوير لاستخدام مهام MediaPipe، بما في ذلك إصدار النظام الأساسي المتطلبات، يُرجى الاطّلاع على دليل الإعداد لنظام التشغيل iOS.

التبعيات

تستخدم ميزة "رصد العناصر" مكتبة MediaPipeTasksVision التي يجب تثبيتها. باستخدام CocoaPods. المكتبة متوافقة مع تطبيقَي Swift وObjective-C ولا تتطلب أي إعداد إضافي خاص بلغة معيّنة.

للحصول على تعليمات حول تثبيت CocoaPods على نظام التشغيل macOS، يُرجى الرجوع إلى مقالة CocoaPods. دليل التركيب. للحصول على تعليمات حول كيفية إنشاء Podfile باستخدام المجموعات الصغيرة اللازمة التطبيق، فارجع إلى استخدام CocoaPods

أضِف لوحة MediaPipeTasksVision في Podfile باستخدام الرمز التالي:

target 'MyObjectDetectorApp' do
  use_frameworks!
  pod 'MediaPipeTasksVision'
end

إذا كان تطبيقك يتضمّن أهداف اختبار وحدات، راجِع دليل إعداد iOS للحصول على معلومات إضافية حول إعداد Podfile.

الطراز

تتطلب مهمة أداة الكشف عن عناصر MediaPipe نموذجًا مدرّبًا ومتوافقًا بهذه المهمة. لمزيد من المعلومات عن النماذج المدربة المتاحة أداة رصد الكائنات، راجِع النظرة العامة على المهمة الطُرز .

اختَر نموذجًا ونزِّله، ثم أضِفه إلى دليل مشروعك باستخدام Xcode. للحصول على تعليمات حول كيفية إضافة ملفات إلى مشروع Xcode، يمكنك الاطّلاع على مقالة إدارة الملفات والمجلدات في Xcode مشروعك.

استخدِم السمة BaseOptions.modelAssetPath لتحديد مسار النموذج. في حِزمة التطبيق. للاطّلاع على مثال على الرمز البرمجي، يُرجى مراجعة القسم التالي.

إنشاء المهمة

يمكنك إنشاء مهمة أداة كشف الكائنات من خلال استدعاء أحد المهيئات. تشير رسالة الأشكال البيانية يضبط برنامج تهيئة ObjectDetector(options:) قيمًا لخيارات الإعداد بما في ذلك وضع التشغيل، واللغة المعروضة للأسماء، والحد الأقصى لعدد النتائج، ومستوى الثقة والحد الأقصى المسموح به للفئات المسموح بها وقائمة الحظر وقائمة الحظر.

إذا لم تكن بحاجة إلى أداة تم إعدادها باستخدام إعدادات مخصَّصة الخيارات، يمكنك استخدام أداة إعداد "ObjectDetector(modelPath:)" لإنشاء أداة رصد العناصر مع الخيارات التلقائية لمزيد من المعلومات عن الإعدادات اطلع على نظرة عامة على التهيئة.

تتوافق مهمة أداة رصد العناصر مع 3 أنواع من بيانات الإدخال: الصور الثابتة وملفات الفيديو. وأحداث الفيديو المباشرة بشكل تلقائي، يتم إعداد ObjectDetector(modelPath:) للصور الثابتة. إذا أردت إعداد مهمتك لمعالجة الفيديو من الملفات أو مجموعات بث فيديو مباشر، استخدِم ObjectDetector(options:) لتحديد الفيديو أو البث المباشر يتطلّب وضع البث المباشر أيضًا objectDetectorLiveStreamDelegate، والذي يُفعّل تعمل أداة رصد العناصر على تقديم نتائج الاكتشاف إلى المفوَّض بشكل غير متزامن.

اختَر علامة التبويب المقابلة لوضع الركض للاطّلاع على كيفية إنشاء المهمة. وإجراء الاستنتاج.

Swift

صورة

import MediaPipeTasksVision

let modelPath = Bundle.main.path(forResource: "model",
                                      ofType: "tflite")

let options = ObjectDetectorOptions()
options.baseOptions.modelAssetPath = modelPath
options.runningMode = .image
options.maxResults = 5

let objectDetector = try ObjectDetector(options: options)
    

فيديو

import MediaPipeTasksVision

let modelPath = Bundle.main.path(forResource: "model",
                                      ofType: "tflite")

let options = ObjectDetectorOptions()
options.baseOptions.modelAssetPath = modelPath
options.runningMode = .video
options.maxResults = 5

let objectDetector = try ObjectDetector(options: options)
    

بث مباشر

import MediaPipeTasksVision

// Class that conforms to the `ObjectDetectorLiveStreamDelegate` protocol and
// implements the method that the object detector calls once it
// finishes performing detection on each input frame.
class ObjectDetectorResultProcessor: NSObject, ObjectDetectorLiveStreamDelegate {

  func objectDetector(
    _ objectDetector: ObjectDetector,
    didFinishDetection objectDetectionResult: ObjectDetectorResult?,
    timestampInMilliseconds: Int,
    error: Error?) {
    // Process the detection result or errors here.
  }
}

let modelPath = Bundle.main.path(forResource: "model",
                                      ofType: "tflite")

let options = ObjectDetectorOptions()
options.baseOptions.modelAssetPath = modelPath
options.runningMode = .liveStream
options.maxResults = 5

// Assign an object of the class to the `objectDetectorLiveStreamDelegate`
// property.
let processor = ObjectDetectorResultProcessor()
options.objectDetectorLiveStreamDelegate = processor

let objectDetector = try ObjectDetector(options: options)
    

Objective-C

صورة

@import MediaPipeTasksVision;

NSString *modelPath = [[NSBundle mainBundle] pathForResource:@"model"
                                                      ofType:@"tflite"];

MPPObjectDetectorOptions *options = [[MPPObjectDetectorOptions alloc] init];
options.baseOptions.modelAssetPath = modelPath;
options.runningMode = MPPRunningModeImage;
options.maxResults = 5;

MPPObjectDetector *objectDetector =
      [[MPPObjectDetector alloc] initWithOptions:options error:nil];
    

فيديو

@import MediaPipeTasksVision;

NSString *modelPath = [[NSBundle mainBundle] pathForResource:@"model"
                                                      ofType:@"tflite"];

MPPObjectDetectorOptions *options = [[MPPObjectDetectorOptions alloc] init];
options.baseOptions.modelAssetPath = modelPath;
options.runningMode = MPPRunningModeVideo;
options.maxResults = 5;

MPPObjectDetector *objectDetector =
      [[MPPObjectDetector alloc] initWithOptions:options error:nil];
    

بث مباشر

@import MediaPipeTasksVision;

// Class that conforms to the `ObjectDetectorLiveStreamDelegate` protocol and
// implements the method that the object detector calls once it
// finishes performing detection on each input frame.

@interface APPObjectDetectorResultProcessor : NSObject 

@end

@implementation MPPObjectDetectorResultProcessor

-   (void)objectDetector:(MPPObjectDetector *)objectDetector
    didFinishDetectionWithResult:(MPPObjectDetectorResult *)ObjectDetectorResult
         timestampInMilliseconds:(NSInteger)timestampInMilliseconds
                           error:(NSError *)error {

    // Process the detection result or errors here.

}

@end

NSString *modelPath = [[NSBundle mainBundle] pathForResource:@"model"
                                                      ofType:@"tflite"];

MPPObjectDetectorOptions *options = [[MPPObjectDetectorOptions alloc] init];
options.baseOptions.modelAssetPath = modelPath;
options.runningMode = MPPRunningModeLiveStream;
options.maxResults = 5;

// Assign an object of the class to the `objectDetectorLiveStreamDelegate`
// property.
APPObjectDetectorResultProcessor *processor = [APPObjectDetectorResultProcessor new];
options.objectDetectorLiveStreamDelegate = processor;

MPPObjectDetector *objectDetector =
      [[MPPObjectDetector alloc] initWithOptions:options error:nil];
    

خيارات الإعداد

تتضمّن هذه المهمة خيارات الضبط التالية لتطبيقات iOS:

اسم الخيار الوصف نطاق القيمة القيمة الافتراضية
runningMode لضبط وضع التشغيل للمهمة. هناك ثلاثة وسائل النقل:

IMAGE: وضع إدخالات الصورة الفردية

فيديو: وضع الإطارات التي تم فك ترميزها لفيديو معيّن

LIVE_STREAM: وضع البث المباشر للإدخال البيانات، مثل تلك الواردة من الكاميرا. في هذا الوضع، يجب أن يكون resultListener يتم استدعاءها لإعداد مستمع للحصول على النتائج بشكل غير متزامن.
{RunningMode.image, RunningMode.video, RunningMode.liveStream} RunningMode.image
displayNamesLocales لتعيين لغة التسميات لاستخدامها في الأسماء المعروضة المقدمة في بيانات التعريف لنموذج المهمة، إن وجد. القيمة التلقائية هي en لمدة الإنجليزية. يمكنك إضافة تصنيفات مترجَمة إلى البيانات الوصفية لنموذج مخصّص. باستخدام TensorFlow Lite Metadata Writer API رمز اللغة en
maxResults يتم ضبط الحد الأقصى الاختياري لنتائج رصد أعلى الدرجات على إرجاع. أي أرقام موجبة -1 (تمّ عرض جميع النتائج)
scoreThreshold لتعيين الحد الأدنى لنتيجة التنبؤ الذي يلغي الحد المقدم في بيانات التعريف للنموذج (إن وجدت). يتم رفض النتائج التي تكون أدنى من هذه القيمة. أي عدد عائم لم يتم ضبط الوضع
categoryAllowlist تضبط هذه السياسة القائمة الاختيارية لأسماء الفئات المسموح بها. إذا لم تكن فارغة، نتائج الكشف التي ليس فيها اسم الفئة في هذه المجموعة بفلترته. ويتم تجاهل أسماء الفئات المكرّرة أو غير المعروفة. لا يمكن لأحد الطرفين استخدام هذا الخيار إلا بعد استخدام categoryDenylist. يؤدي كلا الخيارين إلى خطأ. أي سلاسل لم يتم ضبط الوضع
categoryDenylist تحدِّد هذه السياسة القائمة الاختيارية لأسماء الفئات غير المسموح بها. في حال حذف نتائج الكشف غير الفارغة، التي يوجد اسم فئته بها في هذه المجموعة ستتم تصفيتها . ويتم تجاهل أسماء الفئات المكرّرة أو غير المعروفة. يتوفّر هذا الخيار حصرية مع categoryAllowlist واستخدام النتيجتين معًا إلى حدوث خطأ. أي سلاسل لم يتم ضبط الوضع

إعدادات البث المباشر

عند تعيين وضع التشغيل على البث المباشر، تتطلب أداة كشف الكائنات خيار ضبط إضافي لـ objectDetectorLiveStreamDelegate، والذي يمكّن أداة الكشف من تقديم نتائج الكشف بشكل غير متزامن. المفوَّض لتنفيذ objectDetector(_objectDetector:didFinishDetection:timestampInMilliseconds:error:) التي تستدعيها أداة كشف الكائنات بعد معالجة نتيجة الاكتشاف لكل إطار.

اسم الخيار الوصف نطاق القيمة القيمة الافتراضية
objectDetectorLiveStreamDelegate تُمكِّن أداة كشف الكائنات من تلقّي نتائج الرصد بشكل غير متزامن في البث المباشر. يجب أن تكون الفئة التي تم ضبط مثيلها على هذه السمة تنفيذ objectDetector(_:didFinishDetection:timestampInMilliseconds:error:) . غير منطبق لم يتم ضبط الوضع

تجهيز البيانات

يجب تحويل الصورة المدخلة أو الإطار إلى كائن MPImage قبل وتمريره إلى جهاز كشف الأجسام. يتيح MPImage أنواعًا مختلفة من صور iOS. ويمكنك استخدامها في أي وضع من أوضاع الجري للاستنتاج. لمزيد من المعلومات، المعلومات حول MPImage، فيمكنك الرجوع إلى واجهة برمجة تطبيقات MPImage

اختَر تنسيق صورة لنظام التشغيل iOS بناءً على حالة الاستخدام ووضع الجري. يتطلب التطبيق.MPImage تقبل UIImage وCVPixelBuffer و CMSampleBuffer تنسيقات للصور على نظام التشغيل iOS

UIImage

يناسب تنسيق UIImage تمامًا أوضاع الجري التالية:

  • الصور: صور من حِزمة تطبيق أو معرض مستخدمين أو نظام ملفات بتنسيق يمكن تحويل UIImage صورة إلى عنصر MPImage.

  • الفيديوهات: استخدام AVAssetImageGenerator لاستخراج إطارات الفيديو CGImage ثم قم بتحويلها إلى UIImage صورة.

Swift

// Load an image on the user's device as an iOS `UIImage` object.

// Convert the `UIImage` object to a MediaPipe's Image object having the default
// orientation `UIImage.Orientation.up`.
let image = try MPImage(uiImage: image)
    

Objective-C

// Load an image on the user's device as an iOS `UIImage` object.

// Convert the `UIImage` object to a MediaPipe's Image object having the default
// orientation `UIImageOrientationUp`.
MPImage *image = [[MPPImage alloc] initWithUIImage:image error:nil];
    

يقوم المثال بإعداد MPImage باستخدام الإعداد التلقائي UIImage.Orientation.Up توجهك. يمكنك إعداد MPImage باستخدام أي من الأدوات المتاحة UIImage.Orientation القيم. لا تتوافق أداة رصد الأجسام مع الاتجاهات المعكوسة كالمرآة، مثل .upMirrored .downMirrored و.leftMirrored و.rightMirrored

للحصول على مزيد من المعلومات حول UIImage، يمكنك الرجوع إلى UIImage Apple Developer الوثائق.

CVPixelBuffer

إنّ تنسيق CVPixelBuffer مناسب تمامًا للتطبيقات التي تنشئ إطارات. واستخدام CoreImage لنظام التشغيل iOS إطار عمل المعالجة.

يناسب تنسيق CVPixelBuffer تمامًا أوضاع الجري التالية:

  • الصور: التطبيقات التي تنشئ CVPixelBuffer صورة بعد إجراء بعض المعالجة باستخدام إطار عمل CoreImage في iOS إلى أداة كشف الكائنات في وضع تشغيل الصور.

  • الفيديوهات: يمكن تحويل إطارات الفيديو إلى تنسيق CVPixelBuffer ثم إرسالها إلى أداة كشف الكائنات في وضع الفيديو.

  • البث المباشر: يمكن تحويل التطبيقات التي تستخدم كاميرا iOS لإنشاء الإطارات بتنسيق CVPixelBuffer لمعالجته قبل إرساله إلى أداة رصد الأجسام في وضع البث المباشر

Swift

// Obtain a CVPixelBuffer.

// Convert the `CVPixelBuffer` object to a MediaPipe's Image object having the default
// orientation `UIImage.Orientation.up`.
let image = try MPImage(pixelBuffer: pixelBuffer)
    

Objective-C

// Obtain a CVPixelBuffer.

// Convert the `CVPixelBuffer` object to a MediaPipe's Image object having the
// default orientation `UIImageOrientationUp`.
MPImage *image = [[MPPImage alloc] initWithUIImage:image error:nil];
    

للحصول على مزيد من المعلومات حول "CVPixelBuffer"، يُرجى الرجوع إلى CVPixelBuffer Apple. المطوّر الوثائق.

CMSampleBuffer

يخزِّن التنسيق CMSampleBuffer عينات وسائط من نوع وسائط موحد، مناسبة لوضع الجري في البث المباشر اللقطات المباشرة من كاميرات iOS هي تم العرض بشكل غير متزامن بتنسيق CMSampleBuffer من قِبل نظام التشغيل iOS AVCaptureVideoDataOutput.

Swift

// Obtain a CMSampleBuffer.

// Convert the `CMSampleBuffer` object to a MediaPipe's Image object having the default
// orientation `UIImage.Orientation.up`.
let image = try MPImage(sampleBuffer: sampleBuffer)
    

Objective-C

// Obtain a `CMSampleBuffer`.

// Convert the `CMSampleBuffer` object to a MediaPipe's Image object having the
// default orientation `UIImageOrientationUp`.
MPImage *image = [[MPPImage alloc] initWithSampleBuffer:sampleBuffer error:nil];
    

لمزيد من المعلومات عن CMSampleBuffer، يُرجى الرجوع إلى CMSampleBuffer Apple المطوّر الوثائق.

تنفيذ المهمة

لتشغيل أداة رصد الأجسام، استخدِم الطريقة detect() الخاصة بالأداة المخصّصة وضع الجري:

  • صورة ثابتة: detect(image:)
  • الفيديو: detect(videoFrame:timestampInMilliseconds:)
  • البث المباشر: detectAsync(image:)

تعرض نماذج الرموز التالية أمثلة أساسية حول كيفية تشغيل أداة كشف الكائنات في أوضاع الجري المختلفة:

Swift

صورة

let objectDetector.detect(image:image)
    

فيديو

let objectDetector.detect(videoFrame:image)
    

بث مباشر

let objectDetector.detectAsync(image:image)
    

Objective-C

صورة

MPPObjectDetectorResult *result = [objectDetector detectInImage:image error:nil];
    

فيديو

MPPObjectDetectorResult *result = [objectDetector detectInVideoFrame:image          timestampInMilliseconds:timestamp error:nil];
    

بث مباشر

BOOL success = [objectDetector detectAsyncInImage:image
                          timestampInMilliseconds:timestamp
                                            error:nil];
    

يوضّح مثال رمز أداة رصد العناصر عمليات تنفيذ كل وضع من هذه الأوضاع. بشكل أكثر تفصيلاً detect(image:) وdetect(videoFrame:) و detectAsync(image:) يتيح رمز المثال للمستخدم إمكانية التبديل بين أوضاع المعالجة التي قد لا تكون مطلوبة لحالة الاستخدام.

يُرجى ملاحظة ما يلي:

  • عند تشغيل وضع الفيديو في وضع الفيديو أو وضع البث المباشر، يجب أيضًا توفير: الطابع الزمني لإطار الإدخال إلى مَهمّة أداة رصد العناصر

  • عند التشغيل في وضع الصور أو الفيديو، تمنع مهمة اكتشاف الأشياء سلسلة المحادثات الحالية إلى أن تنتهي من معالجة الصورة أو الإطار الذي تم إدخاله. إلى تجنَّب حظر سلسلة التعليمات الحالية، يُرجى تنفيذ المعالجة في الخلفية. سلسلة محادثات باستخدام iOS Dispatch أو NSOperation وأطر العمل.

  • عند تشغيل مهمة "أداة الكشف عن الأشياء" في وضع البث المباشر، يتم إرجاعها على الفور. ولا يحظر سلسلة المحادثات الحالية إنه يستدعي objectDetector(_objectDetector:didFinishDetection:timestampInMilliseconds:error:) مع نتيجة الكشف بعد معالجة كل إطار إدخال. تشير رسالة الأشكال البيانية تستدعي ميزة "رصد العناصر" هذه الطريقة بشكل غير متزامن على رقم تسلسلي مخصّص. قائمة انتظار الإرسال. لعرض النتائج على واجهة المستخدم، أرسل النتائج إلى قائمة الانتظار الرئيسية بعد معالجة النتائج. إذا كانت السمة detectAsync عندما تكون مهمة "اكتشاف الكائنات" مشغولة بمعالجة مهمة أخرى فإن كاشف الكائنات تتجاهل إطار الإدخال الجديد.

التعامل مع العملاء وعرض النتائج

عند تنفيذ الاستنتاج، تعرض مهمة "أداة رصد الكائنات" ObjectDetectorResult الذي يصف الكائنات التي تم العثور عليها في صورة الإدخال.

في ما يلي مثال على بيانات الإخراج من هذه المهمة:

ObjectDetectorResult:
 Detection #0:
  Box: (x: 355, y: 133, w: 190, h: 206)
  Categories:
   index       : 17
   score       : 0.73828
   class name  : dog
 Detection #1:
  Box: (x: 103, y: 15, w: 138, h: 369)
  Categories:
   index       : 17
   score       : 0.73047
   class name  : dog

تُظهر الصورة التالية تصورًا لنتج المهمة:

يوضّح رمز نموذج أداة رصد العناصر طريقة عرض نتائج الرصد الذي تم إرجاعه من المهمة، راجِع مثال الرمز البرمجي لمعرفة التفاصيل.