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

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

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

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

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

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

تنزيل الرمز

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

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

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

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

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

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

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

تحتوي الملفات التالية على الرمز الأساسي لمثال "مصنِّف الصور" app:

  • 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: وضع إدخالات الصورة الفردية

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

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

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

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

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

تنفيذ المهمة

لتشغيل "مصنِّف الصور"، استخدِم الطريقة 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 وأطر العمل.

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

التعامل مع العملاء وعرض النتائج

عند تنفيذ الاستنتاج، تعرض مهمة مصنف الصور عنصر 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

تم الحصول على هذه النتيجة من خلال تنفيذ مصنِّف الطيور. عَلَى:

يوضّح رمز نموذج أداة تصنيف الصور طريقة عرض التصنيف التي تم إرجاعها من المهمة، راجع التعليمات البرمجية مثال لمزيد من التفاصيل.