تتيح لك مهمة "كاشف الأجسام" رصد توفّر فئات متعددة من الأجسام وموقعها الجغرافي. على سبيل المثال، يمكن لميزة "رصد الأجسام" تحديد موقع الكلاب في الصورة. توضّح لك هذه التعليمات كيفية استخدام مهمة "كاشف الأجسام" في نظام التشغيل iOS. يتوفّر نموذج الرمز البرمجي الموضّح في هذه التعليمات على GitHub.
يمكنك الاطّلاع على هذه المهمة أثناء تنفيذها من خلال مشاهدة هذا العرض التمهيدي لتطبيق الويب. للحصول على مزيد من المعلومات عن إمكانات مهمة هذه ونماذجها وخيارات الضبط، يُرجى الاطّلاع على نظرة عامة.
مثال على الرمز البرمجي
مثال رمز MediaPipe Tasks هو تطبيق أساسي لرصد الأجسام على نظام التشغيل iOS. يستخدم المثال الكاميرا على جهاز iOS مادي لرصد الأجسام باستمرار، ويمكنه أيضًا استخدام الصور والفيديوهات من معرض الصور على الجهاز لرصد الأجسام بشكل ثابت.
يمكنك استخدام التطبيق كنقطة بداية لتطبيقك الخاص على نظام التشغيل iOS، أو الرجوع إليه عند تعديل تطبيق حالي. يتم استضافة مثال الرمز البرمجي لميزة "كاشف الأجسام" على GitHub.
تنزيل الرمز
توضِّح لك التعليمات التالية كيفية إنشاء نسخة محلية من مثال الرمز البرمجي باستخدام أداة سطر الأوامر git.
لتنزيل نموذج الرمز البرمجي:
استنسِخ مستودع git باستخدام الأمر التالي:
git clone https://github.com/google-ai-edge/mediapipe-samples
يمكنك اختياريًا ضبط مثيل git لاستخدام ميزة "الفحص الخفيف"، بحيث تتوفّر لديك فقط ملفات مثال تطبيق "كاشف الأجسام":
cd mediapipe git sparse-checkout init --cone git sparse-checkout set examples/object_detection/ios/
بعد إنشاء نسخة محلية من نموذج الرمز البرمجي، يمكنك تثبيت مكتبة مهام MediaPipe وفتح المشروع باستخدام Xcode وتشغيل التطبيق. للاطّلاع على التعليمات، راجِع دليل الإعداد لنظام التشغيل iOS.
المكونات الرئيسية
تحتوي الملفات التالية على الرمز البرمجي المهم لمثال تطبيق "كاشف الأجسام":
- ObjectDetectorService.swift: تُستخدَم هذه الوظيفة لبدء تشغيل أداة الكشف عن الأجسام واختيار النموذج وتنفيذ الاستنتاجات على بيانات الإدخال.
- CameraViewController.swift: ينفِّذ واجهة المستخدم لوضع إدخال خلاصة الكاميرا المباشرة ويعرض visually نتائج رصد الأجسام.
- 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:)
initializer قيمًا لخيارات الضبط، بما في ذلك وضع التشغيل ولغة الأسماء المعروضة والحد الأقصى لعدد النتائج وحدّ الثقة وقائمة السماح والفئة المحظورة.
إذا لم تكن بحاجة إلى أداة رصد كائنات تم إعدادها باستخدام خيارات ضبط مخصّصة، يمكنك استخدام أداة إعداد 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: وضع الإدخالات باستخدام صورة واحدة. VIDEO: وضع الإطارات التي تم فك ترميزها في الفيديو LIVE_STREAM: وضع البث المباشر لبيانات الإدخال ، مثل بيانات الكاميرا في هذا الوضع، يجب استدعاء resultListener لإعداد مستمع لتلقّي النتائج بشكل غير متزامن. |
{RunningMode.image, RunningMode.video, RunningMode.liveStream } |
RunningMode.image |
displayNamesLocales |
لضبط لغة التصنيفات لاستخدامها في الأسماء المعروضة المقدَّمة في
البيانات الوصفية لنموذج المهمة، في حال توفّرها. القيمة التلقائية هي en لعبارة
English. يمكنك إضافة تصنيفات مترجَمة إلى البيانات الوصفية لنموذج مخصّص
باستخدام واجهة برمجة التطبيقات 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 API.
اختَر تنسيق صورة لنظام التشغيل iOS استنادًا إلى حالة الاستخدام ووضع التشغيل الذي يتطلبه
تطبيقك.يقبلMPImage
تنسيقات صور iOS UIImage
وCVPixelBuffer
و
CMSampleBuffer
.
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
، يُرجى الرجوع إلى مستندات مطوّري تطبيقات Apple المتعلّقة بـ UIImage.
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
، يُرجى الرجوع إلى مستندات "مطوّرو تطبيقات Apple" المتعلقين بـ
CVPixelBuffer.
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
تعرض الصورة التالية عرضًا مرئيًا لمعدّل تكرار المهمة:
يوضّح مثال رمز "أداة رصد الأجسام" كيفية عرض نتائج رصد المُرسَلة من المهمة، اطّلِع على مثال الرمز لمعرفة التفاصيل.