دليل تقسيم الصور لنظام التشغيل iOS

تتيح لك مهمة "تقسيم الصور" تقسيم الصور إلى مناطق بناءً على نموذج محدد مسبقًا وتطبيق التأثيرات البصرية مثل تمويه الخلفية. هذه كيفية استخدام "أداة تقسيم الصور" مع تطبيقات iOS.

يتوفر نموذج التعليمة البرمجية الموضح في هذه التعليمات على GitHub.

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

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

يحتوي مثال التعليمة البرمجية MediaPipe Tasks على تنفيذ بسيط تطبيق Image Segmenter لنظام التشغيل iOS.

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

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

تنزيل الرمز

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

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

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

    git clone https://github.com/google-ai-edge/mediapipe-samples/
    
  2. يمكنك اختياريًا ضبط مثيل 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 مجموعة البيانات

يوضح رمز نموذج أداة تقسيم الصور طريقة عرض أداة تقسيم الصور النتائج، يمكنك الاطّلاع على التعليمات مثال لمزيد من التفاصيل.