راهنمای طبقه بندی تصاویر برای iOS

وظیفه طبقه‌بندی تصویر به شما امکان می‌دهد تا روی تصاویر طبقه‌بندی کنید. شما می توانید از این کار برای شناسایی آنچه که یک تصویر در بین مجموعه ای از دسته بندی های تعریف شده در زمان آموزش نشان می دهد استفاده کنید. این دستورالعمل‌ها به شما نشان می‌دهند که چگونه از Image Classifier در برنامه‌های iOS استفاده کنید. نمونه کد شرح داده شده در این دستورالعمل ها در GitHub موجود است.

شما می توانید با مشاهده این نسخه نمایشی وب، این کار را در عمل مشاهده کنید. برای اطلاعات بیشتر در مورد قابلیت‌ها، مدل‌ها و گزینه‌های پیکربندی این کار، به نمای کلی مراجعه کنید.

نمونه کد

کد مثال MediaPipe Tasks یک پیاده سازی اساسی از برنامه Image Classifier برای iOS است. این مثال از دوربین یک دستگاه فیزیکی iOS برای طبقه‌بندی مداوم اشیا استفاده می‌کند و همچنین می‌تواند از تصاویر و ویدیوهای گالری دستگاه برای طبقه‌بندی استاتیک اشیا استفاده کند.

می‌توانید از برنامه به‌عنوان نقطه شروع برای برنامه iOS خودتان استفاده کنید، یا هنگام تغییر یک برنامه موجود به آن مراجعه کنید. کد نمونه Image Classifier در 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 مراجعه کنید.

اجزای کلیدی

فایل‌های زیر حاوی کد حیاتی برای برنامه مثال طبقه‌بندی کننده تصویر هستند:

  • ImageClassifierService.swift : دسته بندی تصویر را راه اندازی می کند، انتخاب مدل را مدیریت می کند و استنتاج را روی داده های ورودی اجرا می کند.
  • CameraViewController.swift : رابط کاربری را برای حالت ورودی تغذیه زنده دوربین پیاده سازی می کند و نتایج را به تصویر می کشد.
  • MediaLibraryViewController.swift رابط کاربری را برای حالت ورودی تصویر ثابت و فایل ویدیویی پیاده‌سازی می‌کند و نتایج را تجسم می‌کند.

برپایی

این بخش مراحل کلیدی را برای راه اندازی محیط توسعه و پروژه های کد برای استفاده از Image Classifier شرح می دهد. برای اطلاعات کلی در مورد تنظیم محیط توسعه خود برای استفاده از وظایف MediaPipe، از جمله الزامات نسخه پلت فرم، به راهنمای راه اندازی برای iOS مراجعه کنید.

وابستگی ها

Image Classifier از کتابخانه MediaPipeTasksVision استفاده می کند که باید با استفاده از CocoaPods نصب شود. این کتابخانه با هر دو برنامه Swift و Objective-C سازگار است و نیازی به تنظیمات زبان خاصی ندارد.

برای دستورالعمل‌های نصب CocoaPods در macOS، به راهنمای نصب CocoaPods مراجعه کنید. برای دستورالعمل‌های نحوه ایجاد یک Podfile با پادهای لازم برای برنامه خود، به استفاده از CocoaPods مراجعه کنید.

با استفاده از کد زیر، MediaPipeTasksVision pod را در Podfile اضافه کنید:

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

اگر برنامه شما شامل اهداف تست واحد است، برای اطلاعات بیشتر در مورد راه‌اندازی Podfile به راهنمای تنظیم برای iOS مراجعه کنید.

مدل

وظیفه MediaPipe Image Classifier به یک مدل آموزش دیده نیاز دارد که با این کار سازگار باشد. برای اطلاعات بیشتر در مورد مدل‌های آموزش‌دیده موجود برای Image Classifier، بخش مدل‌های نمای کلی کار را ببینید.

یک مدل را انتخاب و دانلود کنید و با استفاده از Xcode آن را به فهرست پروژه خود اضافه کنید. برای دستورالعمل‌هایی درباره نحوه افزودن فایل‌ها به پروژه Xcode، به مدیریت فایل‌ها و پوشه‌ها در پروژه Xcode خود مراجعه کنید.

از ویژگی BaseOptions.modelAssetPath برای تعیین مسیر مدل در بسته نرم افزاری خود استفاده کنید. برای مثال کد، بخش بعدی را ببینید.

کار را ایجاد کنید

می‌توانید با فراخوانی یکی از اولیه‌کننده‌های آن، تکلیف Image Classifier را ایجاد کنید. مقداردهی اولیه ImageClassifier(options:) مقادیری را برای گزینه های پیکربندی شامل حالت اجرا، محل نام های نمایشی، حداکثر تعداد نتایج، آستانه اطمینان، لیست مجاز دسته ها و فهرست رد می کند.

اگر به یک طبقه‌بندی کننده تصویر نیازی ندارید که با گزینه‌های پیکربندی سفارشی‌سازی‌شده مقداردهی شود، می‌توانید از مقداردهی اولیه ImageClassifier(modelPath:) برای ایجاد یک طبقه‌بندی تصویر با گزینه‌های پیش‌فرض استفاده کنید. برای اطلاعات بیشتر درباره گزینه‌های پیکربندی، به نمای کلی پیکربندی مراجعه کنید.

وظیفه طبقه‌بندی کننده تصویر از 3 نوع داده ورودی پشتیبانی می‌کند: تصاویر ثابت، فایل‌های ویدیویی و جریان‌های ویدیویی زنده. به طور پیش فرض، ImageClassifier(modelPath:) یک کار را برای تصاویر ثابت مقداردهی اولیه می کند. اگر می‌خواهید کار شما برای پردازش فایل‌های ویدیویی یا جریان‌های ویدیویی زنده تنظیم شود، از ImageClassifier(options:) برای مشخص کردن حالت اجرای ویدیو یا پخش زنده استفاده کنید. حالت پخش زنده همچنین به گزینه پیکربندی imageClassifierLiveStreamDelegate اضافی نیاز دارد، که طبقه‌بندی کننده تصویر را قادر می‌سازد تا نتایج طبقه‌بندی تصویر را به صورت ناهمزمان به نماینده ارائه کند.

برای مشاهده نحوه ایجاد کار و اجرای استنتاج، برگه مربوط به حالت در حال اجرا خود را انتخاب کنید.

سریع

تصویر

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)
    

هدف-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 است. با استفاده از TensorFlow Lite Metadata Writer API می‌توانید برچسب‌های محلی را به ابرداده یک مدل سفارشی اضافه کنید. کد محلی en
maxResults حداکثر تعداد اختیاری نتایج طبقه بندی با امتیاز بالا را برای بازگشت تنظیم می کند. اگر < 0 باشد، تمام نتایج موجود برگردانده خواهند شد. هر عدد مثبت -1
scoreThreshold آستانه امتیاز پیش‌بینی را تنظیم می‌کند که بر آستانه ارائه‌شده در فراداده مدل (در صورت وجود) لغو می‌شود. نتایج زیر این مقدار رد می شوند. هر شناور تنظیم نشده
categoryAllowlist فهرست اختیاری نام‌های دسته‌بندی مجاز را تنظیم می‌کند. در صورت خالی نبودن، نتایج طبقه بندی که نام دسته آنها در این مجموعه نیست فیلتر می شود. نام‌های دسته‌بندی تکراری یا ناشناخته نادیده گرفته می‌شوند. این گزینه با categoryDenylist منحصر به فرد است و از هر دو نتیجه در یک خطا استفاده می کند. هر رشته تنظیم نشده
categoryDenylist فهرست اختیاری نام‌های دسته‌هایی را که مجاز نیستند را تنظیم می‌کند. در صورت خالی نبودن، نتایج طبقه بندی که نام دسته آنها در این مجموعه است فیلتر می شود. نام‌های دسته‌بندی تکراری یا ناشناخته نادیده گرفته می‌شوند. این گزینه با categoryAllowlist منحصر به فرد است و از هر دو نتیجه در خطا استفاده می کند. هر رشته تنظیم نشده
resultListener شنونده نتیجه را طوری تنظیم می‌کند که وقتی طبقه‌بندی کننده تصویر در حالت پخش زنده است، نتایج طبقه‌بندی را به صورت ناهمزمان دریافت کند. فقط زمانی قابل استفاده است که حالت اجرا روی LIVE_STREAM تنظیم شده باشد N/A تنظیم نشده

پیکربندی پخش زنده

هنگامی که حالت در حال اجرا روی پخش زنده تنظیم می شود، طبقه بندی کننده تصویر به گزینه پیکربندی imageClassifierLiveStreamDelegate اضافی نیاز دارد، که طبقه بندی کننده را قادر می سازد تا نتایج طبقه بندی را به صورت ناهمزمان ارائه دهد. نماینده متد imageClassifier(_:didFinishClassification:timestampInMilliseconds:error:) پیاده سازی می کند که طبقه بندی کننده تصویر پس از پردازش نتایج طبقه بندی برای هر فریم آن را فراخوانی می کند.

نام گزینه شرح محدوده ارزش مقدار پیش فرض
imageClassifierLiveStreamDelegate طبقه‌بندی تصویر را فعال می‌کند تا نتایج طبقه‌بندی را به صورت ناهمزمان در حالت پخش زنده دریافت کند. کلاسی که نمونه آن روی این ویژگی تنظیم شده است باید متد imageClassifier(_:didFinishClassification:timestampInMilliseconds:error:) را پیاده سازی کند. قابل اجرا نیست تنظیم نشده

داده ها را آماده کنید

قبل از ارسال آن به Image Classifier باید تصویر یا فریم ورودی را به یک شی MPImage تبدیل کنید. MPImage از انواع فرمت های تصویر iOS پشتیبانی می کند و می تواند از آنها در هر حالت در حال اجرا برای استنتاج استفاده کند. برای اطلاعات بیشتر در مورد MPImage ، به MPImage API مراجعه کنید

یک قالب تصویر iOS را بر اساس مورد استفاده خود و حالت اجرای مورد نیاز برنامه خود انتخاب کنید. MPImage فرمت‌های تصویر UIImage ، CVPixelBuffer ، و CMSampleBuffer را می‌پذیرد.

تصویر UII

فرمت UIImage برای حالت‌های اجرای زیر مناسب است:

  • تصاویر: تصاویر از یک بسته نرم افزاری، گالری کاربر یا سیستم فایل فرمت شده به عنوان تصاویر UIImage را می توان به یک شی MPImage تبدیل کرد.

  • ویدیوها: از AVAssetImageGenerator برای استخراج فریم های ویدیو به فرمت CGImage استفاده کنید، سپس آنها را به تصاویر UIImage تبدیل کنید.

سریع

// 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)
    

هدف-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 پشتیبانی شده مقداردهی کنید. Image Classifier جهت گیری های آینه شده مانند .upMirrored ، .downMirrored ، .leftMirrored ، .rightMirrored را پشتیبانی نمی کند.

برای اطلاعات بیشتر در مورد UIImage ، به UIImage Apple Developer Documentation مراجعه کنید.

CVPixelBuffer

فرمت CVPixelBuffer برای برنامه هایی که فریم تولید می کنند و از چارچوب CoreImage iOS برای پردازش استفاده می کنند، مناسب است.

فرمت CVPixelBuffer برای حالت‌های اجرای زیر مناسب است:

  • تصاویر: برنامه‌هایی که تصاویر CVPixelBuffer را پس از مدتی پردازش با استفاده از چارچوب CoreImage iOS تولید می‌کنند، می‌توانند در حالت اجرای تصویر به طبقه‌بندی کننده تصویر ارسال شوند.

  • ویدئوها: فریم‌های ویدئو را می‌توان برای پردازش به فرمت CVPixelBuffer تبدیل کرد و سپس در حالت ویدئو به طبقه‌بندی کننده تصویر فرستاد.

  • پخش زنده: برنامه هایی که از دوربین iOS برای تولید فریم استفاده می کنند ممکن است قبل از ارسال به طبقه بندی کننده تصویر در حالت پخش زنده به فرمت CVPixelBuffer برای پردازش تبدیل شوند.

سریع

// 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)
    

هدف-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 مراجعه کنید.

CMSampleBuffer

فرمت CMSampleBuffer نمونه‌های رسانه‌ای از یک نوع رسانه یکنواخت را ذخیره می‌کند و برای حالت پخش زنده مناسب است. قاب‌های زنده دوربین‌های iOS به‌صورت ناهمزمان در قالب CMSampleBuffer توسط iOS AVCaptureVideoDataOutput ارائه می‌شوند.

سریع

// 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)
    

هدف-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 مراجعه کنید.

وظیفه را اجرا کنید

برای اجرای Image Classifier، از متد classify() مخصوص حالت در حال اجرا اختصاص داده شده استفاده کنید:

  • تصویر ثابت: classify(image:)
  • ویدئو: classify(videoFrame:timestampInMilliseconds:)
  • پخش زنده: classifyAsync(image:timestampInMilliseconds:)

Image Classifier دسته بندی های ممکن را برای شیء داخل تصویر یا فریم ورودی برمی گرداند.

نمونه‌های کد زیر نمونه‌های اساسی نحوه اجرای Image Classifier را در این حالت‌های مختلف در حال اجرا نشان می‌دهند:

سریع

تصویر

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

ویدئو

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

پخش زنده

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

هدف-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];
    

مثال کد Image Classifier پیاده‌سازی هر یک از این حالت‌ها classify(videoFrame:timestampInMilliseconds:) با جزئیات بیشتری نشان classifyAsync(image:timestampInMilliseconds:) classify(image:) کد مثال به کاربر اجازه می دهد تا بین حالت های پردازشی که ممکن است برای مورد استفاده شما مورد نیاز نباشد جابجا شود.

به موارد زیر توجه کنید:

  • هنگام اجرا در حالت ویدئو یا حالت پخش زنده، باید مهر زمانی فریم ورودی را نیز به کار طبقه‌بندی کننده تصویر ارائه دهید.

  • هنگامی که در حالت تصویر یا ویدیو اجرا می شود، وظیفه طبقه بندی کننده تصویر رشته فعلی را مسدود می کند تا زمانی که پردازش تصویر یا فریم ورودی به پایان برسد. برای جلوگیری از مسدود کردن رشته فعلی، پردازش را در یک رشته پس‌زمینه با استفاده از چارچوب‌های iOS Dispatch یا NSOperation انجام دهید.

  • هنگامی که در حالت پخش زنده اجرا می شود، وظیفه طبقه بندی کننده تصویر بلافاصله برمی گردد و رشته فعلی را مسدود نمی کند. پس از پردازش هر فریم ورودی، متد imageClassifier(_:didFinishClassification:timestampInMilliseconds:error:) با نتیجه طبقه بندی فراخوانی می کند. Image Classifier این روش را به صورت ناهمزمان در یک صف پخش سریال اختصاصی فراخوانی می کند. برای نمایش نتایج در رابط کاربری، پس از پردازش نتایج، نتایج را به صف اصلی ارسال کنید. اگر تابع classifyAsync زمانی فراخوانی شود که وظیفه طبقه‌بندی کننده تصویر مشغول پردازش فریم دیگری است، طبقه‌بندی کننده تصویر قاب ورودی جدید را نادیده می‌گیرد.

کنترل و نمایش نتایج

پس از اجرای استنتاج، وظیفه 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

این نتیجه با اجرای Bird Classifier در موارد زیر به دست آمده است:

کد نمونه طبقه‌بندی کننده تصویر نحوه نمایش نتایج طبقه‌بندی برگشتی از کار را نشان می‌دهد، برای جزئیات به مثال کد مراجعه کنید.