تتيح لك مهمة "تقسيم الصور" تقسيم الصور إلى مناطق بناءً على نموذج محدد مسبقًا وتطبيق التأثيرات البصرية مثل تمويه الخلفية. هذه كيفية استخدام "أداة تقسيم الصور" مع تطبيقات iOS.
يتوفر نموذج التعليمة البرمجية الموضح في هذه التعليمات على GitHub.
يمكنك رؤية هذه المهمة وهي قيد التنفيذ من خلال عرض صفحة الويب تجريبي. مزيد من المعلومات حول الإمكانات والنماذج وخيارات الضبط هذه المهمة، فراجع نظرة عامة:
مثال على الرمز البرمجي
يحتوي مثال التعليمة البرمجية MediaPipe Tasks على تنفيذ بسيط تطبيق Image Segmenter لنظام التشغيل iOS.
يتم في المثال تنفيذ مقطع صورة يُخرج أقنعة الفئات. تستخدم الكاميرا على جهاز iOS فعلي لإجراء تقسيم الصور في بث مباشر الكاميرا أو على الصور والفيديوهات من معرض الجهاز.
يمكنك استخدام التطبيق كنقطة بداية لتطبيق iOS، أو الرجوع إليه عند تعديل تطبيق حالي. تتم استضافة رمز نموذج أداة تقسيم الصور على GitHub.
تنزيل الرمز
توضّح لك التعليمات التالية كيفية إنشاء نسخة على الجهاز من هذا المثال. باستخدام أداة سطر الأوامر git.
لتنزيل نموذج الرمز:
استنساخ مستودع git باستخدام الأمر التالي:
git clone https://github.com/google-ai-edge/mediapipe-samples/
يمكنك اختياريًا ضبط مثيل git لاستخدام عملية دفع متفرقة، وبالتالي ملفات تطبيق Image Segmenter (نموذج تقسيم الصور) فقط:
cd mediapipe git sparse-checkout init --cone git sparse-checkout set examples/image_segmentation/ios/
بعد إنشاء نسخة محلية من نموذج الرمز، يمكنك تثبيت مكتبة مهام MediaPipe، افتح المشروع باستخدام Xcode وشغِّل التطبيق. بالنسبة التعليمات، راجِع دليل إعداد iOS.
المكوّنات الرئيسية
تحتوي الملفات التالية على الرمز المهم لمثال أداة تقسيم الصور app:
- ImageSegmenterService.swift: تهيئة أداة تقسيم الصور والتعامل مع اختيار النموذج ثم تشغيلها الاستنتاج على بيانات الإدخال.
- CameraViewController.swift: لتنفيذ واجهة المستخدم لوضع إدخال خلاصة الكاميرا المباشرة وعرض نتائجك.
- MediaLibraryViewController.swift لتنفيذ واجهة المستخدم لوضع إدخال الصور الثابتة وملفات الفيديو يتصور النتائج.
ضبط إعدادات الجهاز
يصف هذا القسم الخطوات الرئيسية لإعداد بيئة التطوير في المشروعات البرمجية لاستخدام أداة تقسيم الصور. للحصول على معلومات عامة حول إعداد بيئة تطوير لاستخدام مهام MediaPipe، بما في ذلك إصدار النظام الأساسي المتطلبات، يُرجى الاطّلاع على دليل الإعداد لنظام التشغيل iOS.
التبعيات
تستخدم أداة تقسيم الصور مكتبة MediaPipeTasksVision
التي يجب تثبيتها.
باستخدام CocoaPods. المكتبة متوافقة مع تطبيقَي Swift وObjective-C
ولا تتطلب أي إعداد إضافي خاص بلغة معيّنة.
للحصول على تعليمات حول تثبيت CocoaPods على نظام التشغيل macOS، يُرجى الرجوع إلى مقالة CocoaPods.
دليل التركيب.
للحصول على تعليمات حول كيفية إنشاء Podfile
باستخدام المجموعات الصغيرة اللازمة
التطبيق، راجع استخدام
CocoaPods
أضِف لوحة MediaPipeTasksVision في Podfile
باستخدام الرمز التالي:
target 'MyImageSegmenterApp' do
use_frameworks!
pod 'MediaPipeTasksVision'
end
إذا كان تطبيقك يتضمّن أهداف اختبار وحدات، راجِع دليل إعداد
iOS للحصول على معلومات إضافية حول إعداد
Podfile
.
الطراز
تتطلب مهمة أداة تقسيم صور MediaPipe نموذجًا مدرّبًا ومتوافقًا بهذه المهمة. لمزيد من المعلومات عن النماذج المدربة المتاحة أداة تقسيم الصور، راجع النظرة العامة على المهمة النماذج .
اختَر نموذجًا ونزِّله، ثم أضِفه إلى دليل مشروعك باستخدام Xcode. للحصول على تعليمات حول كيفية إضافة ملفات إلى مشروع Xcode، يمكنك الاطّلاع على مقالة إدارة الملفات والمجلدات في Xcode مشروعك.
استخدِم السمة BaseOptions.modelAssetPath
لتحديد مسار النموذج.
في حِزمة التطبيق. للاطّلاع على مثال على الرمز البرمجي، يُرجى مراجعة القسم التالي.
إنشاء المهمة
يمكنك إنشاء مهمة "أداة تقسيم الصور" من خلال طلب أحد برامج التهيئة. تشير رسالة الأشكال البيانية
يقبل برنامج تهيئة "ImageSegmenter(options:)
" قيم الإعدادات
الخيارات.
في حال لم تكن في حاجة إلى إعداد أداة تقسيم الصور بإعدادات مخصّصة
الخيارات، يمكنك استخدام أداة إعداد "ImageSegmenter(modelPath:)
" لإنشاء
أداة تقسيم الصور مع الخيارات التلقائية. لمزيد من المعلومات عن الإعدادات
اطلع على نظرة عامة على التهيئة.
تتوافق مهمة "أداة تقسيم الصور" مع 3 أنواع من بيانات الإدخال: الصور الثابتة وملفات الفيديو.
وأحداث الفيديو المباشرة بشكل تلقائي، يتم إعداد ImageSegmenter(modelPath:)
للصور الثابتة. إذا أردت إعداد مهمتك لمعالجة الفيديو
من الملفات أو مجموعات بث فيديو مباشر، استخدِم ImageSegmenter(options:)
لتحديد الفيديو
أو البث المباشر يتطلّب وضع البث المباشر أيضًا
imageSegmenterLiveStreamDelegate
، والذي يُفعّل
أداة تقسيم الصور لعرض نتائج تصنيف الصور إلى المفوَّض
بشكل غير متزامن.
اختَر علامة التبويب المقابلة لوضع الركض للاطّلاع على كيفية إنشاء المهمة. وإجراء الاستنتاج.
Swift
صورة
import MediaPipeTasksVision let modelPath = Bundle.main.path(forResource: "model", ofType: "tflite") let options = ImageSegmenterOptions() options.baseOptions.modelAssetPath = modelPath options.runningMode = .image options.shouldOutputCategoryMask = true options.shouldOutputConfidenceMasks = false let imageSegmenter = try ImageSegmenter(options: options)
فيديو
import MediaPipeTasksVision let modelPath = Bundle.main.path(forResource: "model", ofType: "tflite") let options = ImageSegmenterOptions() options.baseOptions.modelAssetPath = modelPath options.runningMode = .video options.shouldOutputCategoryMask = true options.shouldOutputConfidenceMasks = false let imageSegmenter = try ImageSegmenter(options: options)
بث مباشر
import MediaPipeTasksVision // Class that conforms to the `imageSegmenterLiveStreamDelegate` protocol and // implements the method that the image segmenter calls once it finishes // performing segmentation of each input frame. class ImageSegmenterResultProcessor: NSObject, ImageSegmenterLiveStreamDelegate { func imageSegmenter( _ imageSegmenter: ImageSegmenter, didFinishSegmentation result: ImageSegmenterResult?, timestampInMilliseconds: Int, error: Error?) { // Process the image segmentation result or errors here. } } let modelPath = Bundle.main.path(forResource: "model", ofType: "tflite") let options = ImageSegmenterOptions() options.baseOptions.modelAssetPath = modelPath options.runningMode = .liveStream options.shouldOutputCategoryMask = true options.shouldOutputConfidenceMasks = false // Set `imageSegmenterLiveStreamDelegate` to the object of the class that // confirms to the `ImageSegmenterLiveStreamDelegate` protocol. let processor = ImageSegmenterResultProcessor() options.imageSegmenterLiveStreamDelegate = processor let imageSegmenter = try ImageSegmenter(options: options)
Objective-C
صورة
@import MediaPipeTasksVision; NSString *modelPath = [[NSBundle mainBundle] pathForResource:@"model" ofType:@"tflite"]; MPPImageSegmenterOptions *options = [[MPPImageSegmenterOptions alloc] init]; options.baseOptions.modelAssetPath = modelPath; options.runningMode = MPPRunningModeImage; options.shouldOutputCategoryMask = YES; options.shouldOutputConfidenceMasks = NO; MPPImageSegmenter *imageSegmenter = [[MPPImageSegmenter alloc] initWithOptions:options error:nil];
فيديو
@import MediaPipeTasksVision; NSString *modelPath = [[NSBundle mainBundle] pathForResource:@"model" ofType:@"tflite"]; MPPImageSegmenterOptions *options = [[MPPImageSegmenterOptions alloc] init]; options.baseOptions.modelAssetPath = modelPath; options.runningMode = MPPRunningModeVideo; options.shouldOutputCategoryMask = YES; options.shouldOutputConfidenceMasks = NO; MPPImageSegmenter *imageSegmenter = [[MPPImageSegmenter alloc] initWithOptions:options error:nil];
بث مباشر
@import MediaPipeTasksVision; // Class that conforms to the `MPPImageSegmenterLiveStreamDelegate` protocol // and implements the method that the image segmenter calls once it finishes // performing segmentation of each input frame. @interface APPImageSegmenterResultProcessor : NSObject@end @implementation APPImageSegmenterResultProcessor - (void)imageSegmenter:(MPPImageSegmenter *)imageSegmenter didFinishSegmentationWithResult:(MPPImageSegmenterResult *)imageSegmenterResult timestampInMilliseconds:(NSInteger)timestampInMilliseconds error:(NSError *)error { // Process the image segmentation result or errors here. } @end NSString *modelPath = [[NSBundle mainBundle] pathForResource:@"model" ofType:@"tflite"]; MPPImageSegmenterOptions *options = [[MPPImageSegmenterOptions alloc] init]; options.baseOptions.modelAssetPath = modelPath; options.runningMode = MPPRunningModeLiveStream; options.shouldOutputCategoryMask = YES; options.shouldOutputConfidenceMasks = NO; // Set `imageSegmenterLiveStreamDelegate` to the object of the class that // confirms to the `MPPImageSegmenterLiveStreamDelegate` protocol. APPImageSegmenterResultProcessor *processor = [APPImageSegmenterResultProcessor new]; options.imageSegmenterLiveStreamDelegate = processor; MPPImageSegmenter *imageSegmenter = [[MPPImageSegmenter alloc] initWithOptions:options error:nil];
يسمح نموذج تنفيذ رمز أداة تقسيم الصور للمستخدم بالتبديل بين أوضاع المعالجة. تجعل هذه الطريقة رمز إنشاء المهمة أكثر تعقيدًا قد لا تكون مناسبة لحالة الاستخدام لديك.
خيارات الإعداد
تتضمّن هذه المهمة خيارات الضبط التالية لتطبيقات iOS:
اسم الخيار | الوصف | نطاق القيمة | القيمة الافتراضية |
---|---|---|---|
runningMode |
لضبط وضع التشغيل للمهمة. هناك ثلاثة
وسائل النقل: IMAGE: وضع إدخالات الصورة الفردية فيديو: وضع الإطارات التي تم فك ترميزها لفيديو معيّن LIVE_STREAM: وضع البث المباشر للإدخال البيانات، مثل تلك الواردة من الكاميرا. في هذا الوضع، ImageSegmenterLiveStreamDelegate
على مثيل لفئة تنفذ
ImageSegmenterLiveStreamDelegate للحصول على التصنيف
بشكل غير متزامن.
|
{RunningMode.image, RunningMode.video, RunningMode.liveStream } |
RunningMode.image |
shouldOutputCategoryMask |
في حال ضبط القيمة على True ، سيشمل الناتج قناع تصنيف إلى شرائح.
كصورة uint8، حيث تشير كل قيمة بكسل إلى الفئة الفائزة
|
{True, False } |
False |
shouldOutputConfidenceMasks |
في حال ضبط القيمة على True ، سيشمل الناتج قناع تصنيف إلى شرائح.
كصورة قيمة عائمة، حيث تمثل كل قيمة عائمة الثقة
خريطة النقاط للفئة. |
{True, False } |
True |
displayNamesLocale |
لتعيين لغة التسميات لاستخدامها في الأسماء المعروضة المقدمة في
بيانات التعريف لنموذج المهمة، إن وجد. القيمة التلقائية هي en لمدة
الإنجليزية. يمكنك إضافة تصنيفات مترجَمة إلى البيانات الوصفية لنموذج مخصّص.
باستخدام TensorFlow Lite Metadata Writer API |
رمز اللغة | en |
result_callback |
تعيين أداة معالجة النتائج لتلقّي نتائج التقسيم
بشكل غير متزامن عندما يكون أداة تقسيم الصور في وضع LIVE_STREAM .
لا يمكن استخدام الإذن إلا عند ضبط "وضع التشغيل" على LIVE_STREAM |
لا ينطبق | لا ينطبق |
عند ضبط وضع التشغيل على LIVE_STREAM
، تتطلب "أداة تقسيم الصور"
خيار ضبط إضافي لـ imageSegmenterLiveStreamDelegate
، والذي
يمكّن "أداة تقسيم الصور" من تقديم نتائج تصنيف الصور إلى شرائح بشكل غير متزامن.
على المفوَّض تنفيذ
طريقة واحدة (imageSegmenter(_:didFinishSegmentation:timestampInMilliseconds:error:)
)،
التي تستدعيها أداة تقسيم الصور بعد معالجة نتائج
التقسيم على كل إطار.
اسم الخيار | الوصف | نطاق القيمة | القيمة الافتراضية |
---|---|---|---|
imageSegmenterLiveStreamDelegate |
تفعيل أداة تقسيم الصور من أجل تلقّي نتائج أداء الصورة
التقسيم بشكل غير متزامن في وضع البث المباشر. الفئة التي يكون مثيلها
المعينة على هذه السمة أن تنفذ
imageSegmenter(_:didFinishSegmentation: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
المطوّر
الوثائق.
تنفيذ المهمة
لتشغيل "أداة تقسيم الصور"، استخدِم الطريقة segment()
الخاصة بالعنصر
وضع الجري:
- صورة ثابتة:
segment(image:)
- الفيديو:
segment(videoFrame:timestampInMilliseconds:)
- بث مباشر:
segmentAsync(image:timestampInMilliseconds:)
تعرض نماذج التعليمات البرمجية التالية أمثلة بسيطة لكيفية تشغيل أداة تقسيم الصور في أوضاع الجري المختلفة:
Swift
صورة
let result = try imageSegmenter.segment(image: image)
فيديو
let result = try imageSegmenter.segment( videoFrame: image, timestampInMilliseconds: timestamp)
بث مباشر
try imageSegmenter.segmentAsync( image: image, timestampInMilliseconds: timestamp)
Objective-C
صورة
MPPImageSegmenterResult *result = [imageSegmenter segmentImage:image error:nil];
فيديو
MPPImageSegmenterResult *result = [imageSegmenter segmentVideoFrame:image timestampInMilliseconds:timestamp error:nil];
بث مباشر
BOOL success = [imageSegmenter segmentAsyncImage:image timestampInMilliseconds:timestamp error:nil];
يوضّح مثال رمز أداة تقسيم الصور عمليات تنفيذ كل وضع من هذه الأوضاع.
بمزيد من التفصيل segment(image:)
،
segment(videoFrame:timestampInMilliseconds:)
و
segmentAsync(image:timestampInMilliseconds:)
يُرجى ملاحظة ما يلي:
عند تشغيل وضع الفيديو أو وضع البث المباشر، يجب أيضًا توفير الطابع الزمني لإطار الإدخال لمهمة أداة تقسيم الصور
عند التشغيل في وضع الصور أو الفيديو، تمنع مهمة أداة تقسيم الصور سلسلة المحادثات الحالية إلى أن تنتهي من معالجة الصورة أو الإطار الذي تم إدخاله. إلى تجنَّب حظر سلسلة التعليمات الحالية، يُرجى تنفيذ المعالجة في الخلفية. سلسلة محادثات باستخدام iOS Dispatch أو NSOperation وأطر العمل.
عند تفعيل "وضع البث المباشر"، يتم إرجاع مهمة "أداة تقسيم الصور" على الفور. ولا يحظر سلسلة المحادثات الحالية إنه يستدعي
imageSegmenter(_:didFinishSegmentation:timestampInMilliseconds:error:)
مع أداة تقسيم الصور بعد معالجة كل إطار إدخال. تشير رسالة الأشكال البيانية تستدعي "أداة تقسيم الصور" هذه الطريقة بشكل غير متزامن على رقم تسلسلي مخصّص قائمة انتظار الإرسال. لعرض النتائج على واجهة المستخدم، أرسل النتائج إلى قائمة الانتظار الرئيسية بعد معالجة النتائج. إذا كانت يتم استدعاء الدالةsegmentAsync
عندما تكون مهمة أداة تقسيم الصور مشغولة. عند معالجة إطار آخر، تتجاهل أداة تقسيم الصور إطار الإدخال الجديد.
التعامل مع العملاء وعرض النتائج
عند تشغيل الاستنتاج، تعرض مهمة أداة تقسيم الصور ImageSegmenterResult
الذي يحتوي على نتائج مهمة التصنيف إلى شرائح. يتضمن محتوى
على نوع الإخراج الذي تضبطه عند
تم الإعداد
للمهمة.
تعرض الصور التالية تصورًا لمخرجات المهمة لفئة ما
قناع القيمة. نطاق قناع الفئة هو [0, 255]
وقيمة كل قيمة بكسل.
مؤشر الفئة الفائز لمخرجات النموذج. الفئة الفائزة
على أعلى درجة بين الفئات التي يمكن أن يتعرف عليها النموذج.
إخراج قناع الصورة الأصلي والفئة: صورة المصدر من Pascal VOC 2012 مجموعة البيانات
يوضح رمز نموذج أداة تقسيم الصور طريقة عرض أداة تقسيم الصور النتائج، يمكنك الاطّلاع على التعليمات مثال لمزيد من التفاصيل.