تتيح لك مهمة "مُقسِّم الصور" تقسيم الصور إلى مناطق استنادًا إلى ملف شخصي مُحدّد مسبقًا، وتطبيق تأثيرات مرئية مثل تمويه الخلفية. توضّح لك هذه التعليمات كيفية استخدام أداة "تقسيم الصور" مع تطبيقات iOS.
يتوفّر نموذج الرمز البرمجي الموضّح في هذه التعليمات على GitHub.
يمكنك الاطّلاع على هذه المهمة وهي قيد التنفيذ من خلال الاطّلاع على العرض التوضيحي للويب. لمزيد من المعلومات عن الإمكانات والنماذج وخيارات الضبط لهذه المهمة، اطّلِع على نظرة عامة.
مثال على الرمز البرمجي
يحتوي مثال رمز MediaPipe Tasks على تنفيذ بسيط لتطبيق Image Segmenter لنظام التشغيل 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/image_segmentation/ios/
بعد إنشاء نسخة محلية من نموذج الرمز البرمجي، يمكنك تثبيت مكتبة مهام MediaPipe وفتح المشروع باستخدام Xcode وتشغيل التطبيق. للاطّلاع على التعليمات، راجِع دليل الإعداد لنظام التشغيل iOS.
المكوّنات الرئيسية
تحتوي الملفات التالية على الرمز البرمجي المهم لتطبيق مثال "مُقسِّم الصور" :
- ImageSegmenterService.swift: تُستخدَم هذه الوظيفة لإعداد أداة "تقسيم الصور" ومعالجة اختيار النموذج وتنفيذ عملية التنقّل في البيانات المُدخلة.
- CameraViewController.swift: ينفِّذ واجهة المستخدم لوضع إدخال خلاصة الكاميرا المباشرة ويعرض visually results.
- 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 لعبارة
English. يمكنك إضافة تصنيفات مترجَمة إلى البيانات الوصفية لنموذج مخصّص
باستخدام واجهة برمجة التطبيقات 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 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
، يمكنك الاطّلاع على وثائق مطوّري
أعمال 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
، يُرجى الاطّلاع على وثائق مطوّري
برامج Apple CMSampleBuffer.
تنفيذ المهمة
لتشغيل أداة "تقسيم الصور"، استخدِم طريقة 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.
يوضّح مثال الرمز البرمجي لواحدة من ميزات "تقسيم الصور" كيفية عرض نتائجها، اطّلِع على مثال الرمز البرمجي للاطّلاع على التفاصيل.