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

تتيح لك مهمة "مصنِّف الصور" إجراء تصنيف للصور. يمكنك استخدام هذه المهمة لتحديد ما تمثله الصورة من بين مجموعة من الفئات المحدّدة في وقت التدريب. توضّح لك هذه التعليمات كيفية استخدام "مصنِّف الصور" في تطبيقات iOS. يتوفّر نموذج الرمز البرمجي الموضّح في هذه التعليمات على GitHub.

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

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

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

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

تنزيل الرمز

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

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

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

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

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

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

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

تحتوي الملفات التالية على الرمز البرمجي المهم لتطبيق مثال "مصنِّف الصور":

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

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

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

التبعيات

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

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

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

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

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

الطراز

تتطلّب مهمة "تصنيف الصور" في MediaPipe نموذجًا مدرَّبًا متوافقًا مع هذه المهمة. لمزيد من المعلومات عن النماذج المدربة المتاحة لميزة "تصنيف الصور"، اطّلِع على قسم نماذج ضمن النظرة العامة على المهمة.

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

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

إنشاء المهمة

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

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

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

اختَر علامة التبويب المناسبة لوضع التشغيل لمعرفة كيفية إنشاء المهمة وتنفيذ الاستنتاج.

Swift

صورة

import MediaPipeTasksVision

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

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

let imageClassifier = try ImageClassifier(options: options)
    

فيديو

import MediaPipeTasksVision

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

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

let imageClassifier = try ImageClassifier(options: options)
    

بث مباشر

import MediaPipeTasksVision

// Class that conforms to the `ImageClassifierLiveStreamDelegate` protocol and
// implements the method that the image classifier calls once it
// finishes performing classification on each input frame.
class ImageClassifierResultProcessor: NSObject, ImageClassifierLiveStreamDelegate {

   func imageClassifier(
    _ imageClassifier: ImageClassifier,
    didFinishClassification result: ImageClassifierResult?,
    timestampInMilliseconds: Int,
    error: Error?) {

    // Process the image classifier result or errors here.

  }
}

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

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

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

let imageClassifier = try ImageClassifier(options: options)
    

Objective-C

صورة

@import MediaPipeTasksVision;

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

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

MPPImageClassifier *imageClassifier =
      [[MPPImageClassifier alloc] initWithOptions:options error:nil];
    

فيديو

@import MediaPipeTasksVision;

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

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

MPPImageClassifier *imageClassifier =
      [[MPPImageClassifier alloc] initWithOptions:options error:nil];
    

بث مباشر

@import MediaPipeTasksVision;

// Class that conforms to the `MPPImageClassifierLiveStreamDelegate` protocol
// and implements the method that the image classifier calls once it finishes
// performing classification on each input frame.

@interface APPImageClassifierResultProcessor : NSObject 

@end

@implementation APPImageClassifierResultProcessor

-   (void)imageClassifier:(MPPImageClassifier *)imageClassifier
    didFinishClassificationWithResult:(MPPImageClassifierResult *)imageClassifierResult
              timestampInMilliseconds:(NSInteger)timestampInMilliseconds
                                error:(NSError *)error {

    // Process the image classifier result or errors here.

}

@end

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

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

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

MPPImageClassifier *imageClassifier =
      [[MPPImageClassifier alloc] initWithOptions:options error:nil];
    

خيارات الضبط

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

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

IMAGE: وضع الإدخالات المكوّنة من صورة واحدة.

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

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

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

عند ضبط وضع التشغيل على "البث المباشر"، يتطلّب "تصنيف الصور" استخدام خيار الإعداد imageClassifierLiveStreamDelegate الإضافي، الذي يتيح للتصنيف تقديم نتائج التصنيف بشكل غير متزامن. ينفِّذ الوكيل الأسلوب imageClassifier(_:didFinishClassification:timestampInMilliseconds:error:) الذي يستدعيه "تصنيف الصور" بعد معالجة نتائج التصنيف لكل إطار.

اسم الخيار الوصف نطاق القيمة القيمة التلقائية
imageClassifierLiveStreamDelegate يتيح هذا الخيار لـ "مصنِّف الصور" تلقّي نتائج التصنيف بشكل غير متزامن في وضع البث المباشر. يجب أن تنفّذ الفئة التي تم ضبط مثيلها على هذه السمة imageClassifier(_:didFinishClassification: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 لمعالجتها قبل إرسالها إلى Image Classifier في وضع البث المباشر.

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، يُرجى الاطّلاع على وثائق مطوّري برامج Apple CMSampleBuffer.

تنفيذ المهمة

لتشغيل "مصنِّف الصور"، استخدِم الطريقة classify() الخاصة بوضع التشغيل المخصّص:

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

يعرض مصنِّف الصور الفئات المحتملة للكائن داخل إطار الإدخال أو الصورة.

تعرض نماذج الرموز التالية أمثلة أساسية حول كيفية تشغيل "مصنِّف الصور" في أوضاع التشغيل المختلفة هذه:

Swift

صورة

let result = try imageClassifier.classify(image: image)
    

فيديو

let result = try imageClassifier.classify(
  videoFrame: image,
  timestampInMilliseconds: timestamp)
    

بث مباشر

try imageClassifier.classifyAsync(
  image: image,
  timestampInMilliseconds: timestamp)
    

Objective-C

صورة

MPPImageClassifierResult *result = [imageClassifier classifyImage:image
                                                            error:nil];
    

فيديو

MPPImageClassifierResult *result = [imageClassifier classifyVideoFrame:image
                                               timestampInMilliseconds:timestamp
                                                                 error:nil];
    

بث مباشر

BOOL success = [imageClassifier classifyAsyncImage:image
                          timestampInMilliseconds:timestamp
                                            error:nil];
    

يعرض مثال رمز "تصنيف الصور" عمليات تنفيذ كلٍّ من هذه الأوضاع بمزيد من التفصيل classify(image:)، classify(videoFrame:timestampInMilliseconds:)، classifyAsync(image:timestampInMilliseconds:). يسمح مثال الرمز للمستخدم بالتبديل بين أوضاع المعالجة التي قد لا تكون مطلوبة لحالة الاستخدام.

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

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

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

  • عند التشغيل في وضع البث المباشر، تُعرض مهمة Image Classifier على الفور ولا تحظر سلسلة المحادثات الحالية. ويُستخدَم الأسلوب imageClassifier(_:didFinishClassification:timestampInMilliseconds:error:) مع نتيجة التصنيف بعد معالجة كل لقطة إدخال. يستدعي "مصنِّف الصور" هذه الطريقة بشكل غير متزامن في "قائمة إرسال" متسلسلة مخصّصة. لعرض النتائج على واجهة المستخدم، يُرجى إرسال النتائج إلى قائمة الانتظار الرئيسية بعد معالجة النتائج. إذا تمّ استدعاء الدالة classifyAsync عندما تكون مهمة Image Classifier مشغولة بمعالجة إطار آخر، يتجاهل Image Classifier إطار الإدخال الجديد.

معالجة النتائج وعرضها

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

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

ImageClassifierResult:
 Classifications #0 (single classification head):
  head index: 0
  category #0:
   category name: "/m/01bwb9"
   display name: "Passer domesticus"
   score: 0.91406
   index: 671
  category #1:
   category name: "/m/01bwbt"
   display name: "Passer montanus"
   score: 0.00391
   index: 670

تم الحصول على هذه النتيجة من خلال تشغيل أداة تصنيف الطيور على:

يوضّح مثال الرمز البرمجي لمُصنِّف الصور كيفية عرض نتائج التصنيف المعروضة من المهمة، اطّلِع على مثال الرمز البرمجي لمعرفة التفاصيل.