تصنيف الصور باستخدام نموذج تم تدريبه على AutoML على نظام التشغيل iOS
بعد تدريب نموذجك الخاص باستخدام AutoML Vision Edge، يمكنك استخدامها في التطبيق لتصنيف الصور.
هناك طريقتان لدمج النماذج التي تم تدريبها من AutoML Vision Edge. يمكنك وحزم النموذج عن طريق نسخ ملفات النموذج إلى مشروع Xcode، أو تنزيل التطبيق ديناميكيًا من Firebase
خيارات تجميع النموذج | |
---|---|
مُجمَّعة في تطبيقك |
|
مستضاف باستخدام Firebase |
|
جرّبه الآن
- يمكنك تجربة نموذج التطبيق من أجل يمكنك الاطّلاع على مثال حول استخدام واجهة برمجة التطبيقات هذه.
قبل البدء
1. تضمين مكتبات ML Kit في Podfile:لتجميع نموذج مع تطبيقك:
pod 'GoogleMLKit/ImageLabelingAutoML'لتنزيل نموذج من Firebase ديناميكيًا، أضِف
LinkFirebase
.
التبعية:
pod 'GoogleMLKit/ImageLabelingAutoML' pod 'GoogleMLKit/LinkFirebase'2- بعد تثبيت لوحات مشروعك أو تحديثها، افتح مشروع Xcode الخاص بك. باستخدام
.xcworkspace
الرمز> تتوفّر حزمة تعلّم الآلة في Xcode
الإصدار 13.2.1 أو الإصدارات الأحدث.
3- إذا كنت تريد تنزيل نموذج، تأكد من
إضافة Firebase إلى مشروع iOS
إذا لم تكن قد قمت بذلك بالفعل. هذا الإجراء غير مطلوب عند تجميع
الأمثل.
1. تحميل النموذج
إعداد مصدر نموذج محلي
لدمج النموذج مع تطبيقك:1- يمكنك استخراج النموذج وبياناته الوصفية من أرشيف ZIP الذي نزّلته. من "وحدة تحكُّم Firebase" إلى مجلد:
your_model_directory |____dict.txt |____manifest.json |____model.tfliteيجب أن تكون الملفات الثلاثة جميعها في مجلد واحد. ننصحك باستخدام الملفات أثناء تنزيلها، بدون تعديل (بما في ذلك أسماء الملفات).
2- انسخ المجلد إلى مشروع Xcode، مع الحرص على تحديد أنشئ مراجع للمجلدات عند إجراء ذلك. ملف النموذج وبيانات التعريف سيتم تضمينه في حِزمة التطبيق وإتاحتها في حزمة تعلّم الآلة.
3- إنشاء كائن
AutoMLImageLabelerLocalModel
، مع تحديد المسار إلى
ملف بيان النموذج:
Swift
guard let manifestPath = Bundle.main.path( forResource: "manifest", ofType: "json", inDirectory: "your_model_directory" ) else { return } let localModel = AutoMLImageLabelerLocalModel(manifestPath: manifestPath)
Objective-C
NSString *manifestPath = [NSBundle.mainBundle pathForResource:@"manifest" ofType:@"json" inDirectory:@"your_model_directory"]; MLKAutoMLImageLabelerLocalModel *localModel = [[MLKAutoMLImageLabelerLocalModel alloc] initWithManifestPath:manifestPath];
ضبط مصدر نموذج مستضاف على Firebase
لاستخدام النموذج المستضاف عن بُعد، عليك إنشاء AutoMLImageLabelerRemoteModel
محدد، مع تحديد الاسم الذي عينته للنموذج عند نشره:
Swift
let remoteModel = AutoMLImageLabelerRemoteModel( name: "your_remote_model" // The name you assigned in // the Firebase console. )
Objective-C
MLKAutoMLImageLabelerRemoteModel *remoteModel = [[MLKAutoMLImageLabelerRemoteModel alloc] initWithName:@"your_remote_model"]; // The name you assigned in // the Firebase console.
بعد ذلك، ابدأ مهمة تنزيل النموذج، مع تحديد الشروط التي الذي تريد السماح بتنزيله إذا لم يكن الطراز موجودًا على الجهاز، أو إذا كان طرازًا أحدث إتاحة إصدار معين من النموذج، فإن المهمة ستنزّل بشكل غير متزامن النموذج من Firebase:
Swift
let downloadConditions = ModelDownloadConditions( allowsCellularAccess: true, allowsBackgroundDownloading: true ) let downloadProgress = ModelManager.modelManager().download( remoteModel, conditions: downloadConditions )
Objective-C
MLKModelDownloadConditions *downloadConditions = [[MLKModelDownloadConditions alloc] initWithAllowsCellularAccess:YES allowsBackgroundDownloading:YES]; NSProgress *downloadProgress = [[MLKModelManager modelManager] downloadModel:remoteModel conditions:downloadConditions];
تبدأ العديد من التطبيقات مهمة التنزيل في رمز التهيئة الخاص بها، ولكن يمكنك القيام بذلك في أي وقت قبل أن تحتاج إلى استخدام النموذج.
إنشاء مصنِّف للصور من نموذجك
بعد ضبط مصادر النموذج، أنشِئ عنصر ImageLabeler
من أحد العناصر.
منها.
وإذا كان لديك نموذج مجمّع محليًا فقط، ما عليك سوى إنشاء مصنِّف من
كائن "AutoMLImageLabelerLocalModel
" وضبط نتيجة الثقة
المطلوب الحصول عليه (يُرجى الاطّلاع على تقييم وضعك:
Swift
let options = AutoMLImageLabelerOptions(localModel: localModel) options.confidenceThreshold = NSNumber(value: 0.0) // Evaluate your model in the Firebase console // to determine an appropriate value. let imageLabeler = ImageLabeler.imageLabeler(options: options)
Objective-C
MLKAutoMLImageLabelerOptions *options = [[MLKAutoMLImageLabelerOptions alloc] initWithLocalModel:localModel]; options.confidenceThreshold = @(0.0); // Evaluate your model in the Firebase console // to determine an appropriate value. MLKImageLabeler *imageLabeler = [MLKImageLabeler imageLabelerWithOptions:options];
فإذا كان لديك نموذج مستضاف عن بُعد، فعليك التحقق من أنه
تم تنزيله قبل تشغيله. يمكنك التحقّق من حالة تنزيل النموذج
باستخدام طريقة isModelDownloaded
(remoteModel:) التابع لمدير النماذج.
وما عليك سوى تأكيد هذا قبل تشغيل المُصنِّف، إذا
لكل من نموذج مُستضاف عن بُعد ونموذج مُجمع محليًا، فقد تجعل
إجراء عملية الفحص هذه عند إنشاء مثيل ImageLabeler
: إنشاء
من النموذج البعيد إذا تم تنزيله، ومن النموذج المحلي
وإلا.
Swift
var options: AutoMLImageLabelerOptions! if (ModelManager.modelManager().isModelDownloaded(remoteModel)) { options = AutoMLImageLabelerOptions(remoteModel: remoteModel) } else { options = AutoMLImageLabelerOptions(localModel: localModel) } options.confidenceThreshold = NSNumber(value: 0.0) // Evaluate your model in the Firebase console // to determine an appropriate value. let imageLabeler = ImageLabeler.imageLabeler(options: options)
Objective-C
MLKAutoMLImageLabelerOptions *options; if ([[MLKModelManager modelManager] isModelDownloaded:remoteModel]) { options = [[MLKAutoMLImageLabelerOptions alloc] initWithRemoteModel:remoteModel]; } else { options = [[MLKAutoMLImageLabelerOptions alloc] initWithLocalModel:localModel]; } options.confidenceThreshold = @(0.0); // Evaluate your model in the Firebase console // to determine an appropriate value. MLKImageLabeler *imageLabeler = [MLKImageLabeler imageLabelerWithOptions:options];
وإذا كان لديك نموذج مستضاف عن بُعد فقط، يجب إيقاف النموذج المرتبط بالنموذج الوظائف - على سبيل المثال، إخفاء جزء من واجهة المستخدم أو جعلها رمادية حتى التأكد من تنزيل النموذج.
يمكنك الحصول على حالة تنزيل النموذج من خلال إرفاق عناصر المراقبين بالإعداد التلقائي.
مركز الإشعارات. تأكد من استخدام إشارة ضعيفة إلى self
في المراقب
حظر، نظرًا لأن عمليات التنزيل قد تستغرق بعض الوقت وقد يتم حذف الكائن الأصلي
ويتم تحريره عند انتهاء التنزيل. على سبيل المثال:
Swift
NotificationCenter.default.addObserver( forName: .mlkitModelDownloadDidSucceed, object: nil, queue: nil ) { [weak self] notification in guard let strongSelf = self, let userInfo = notification.userInfo, let model = userInfo[ModelDownloadUserInfoKey.remoteModel.rawValue] as? RemoteModel, model.name == "your_remote_model" else { return } // The model was downloaded and is available on the device } NotificationCenter.default.addObserver( forName: .mlkitModelDownloadDidFail, object: nil, queue: nil ) { [weak self] notification in guard let strongSelf = self, let userInfo = notification.userInfo, let model = userInfo[ModelDownloadUserInfoKey.remoteModel.rawValue] as? RemoteModel else { return } let error = userInfo[ModelDownloadUserInfoKey.error.rawValue] // ... }
Objective-C
__weak typeof(self) weakSelf = self; [NSNotificationCenter.defaultCenter addObserverForName:MLKModelDownloadDidSucceedNotification object:nil queue:nil usingBlock:^(NSNotification *_Nonnull note) { if (weakSelf == nil | note.userInfo == nil) { return; } __strong typeof(self) strongSelf = weakSelf; MLKRemoteModel *model = note.userInfo[MLKModelDownloadUserInfoKeyRemoteModel]; if ([model.name isEqualToString:@"your_remote_model"]) { // The model was downloaded and is available on the device } }]; [NSNotificationCenter.defaultCenter addObserverForName:MLKModelDownloadDidFailNotification object:nil queue:nil usingBlock:^(NSNotification *_Nonnull note) { if (weakSelf == nil | note.userInfo == nil) { return; } __strong typeof(self) strongSelf = weakSelf; NSError *error = note.userInfo[MLKModelDownloadUserInfoKeyError]; }];
2. تحضير صورة الإدخال
إنشاء عنصر VisionImage
باستخدام UIImage
أو
CMSampleBuffer
إذا كنت تستخدم UIImage
، يُرجى اتّباع الخطوات التالية:
- أنشئ كائن
VisionImage
باستخدامUIImage
. تأكَّد من تحديد قيمة.orientation
الصحيحة.Swift
let image = VisionImage(image: UIImage) visionImage.orientation = image.imageOrientation
Objective-C
MLKVisionImage *visionImage = [[MLKVisionImage alloc] initWithImage:image]; visionImage.orientation = image.imageOrientation;
إذا كنت تستخدم CMSampleBuffer
، يُرجى اتّباع الخطوات التالية:
-
حدد اتجاه بيانات الصورة المضمنة في
CMSampleBuffer
للحصول على اتجاه الصورة:
Swift
func imageOrientation( deviceOrientation: UIDeviceOrientation, cameraPosition: AVCaptureDevice.Position ) -> UIImage.Orientation { switch deviceOrientation { case .portrait: return cameraPosition == .front ? .leftMirrored : .right case .landscapeLeft: return cameraPosition == .front ? .downMirrored : .up case .portraitUpsideDown: return cameraPosition == .front ? .rightMirrored : .left case .landscapeRight: return cameraPosition == .front ? .upMirrored : .down case .faceDown, .faceUp, .unknown: return .up } }
Objective-C
- (UIImageOrientation) imageOrientationFromDeviceOrientation:(UIDeviceOrientation)deviceOrientation cameraPosition:(AVCaptureDevicePosition)cameraPosition { switch (deviceOrientation) { case UIDeviceOrientationPortrait: return cameraPosition == AVCaptureDevicePositionFront ? UIImageOrientationLeftMirrored : UIImageOrientationRight; case UIDeviceOrientationLandscapeLeft: return cameraPosition == AVCaptureDevicePositionFront ? UIImageOrientationDownMirrored : UIImageOrientationUp; case UIDeviceOrientationPortraitUpsideDown: return cameraPosition == AVCaptureDevicePositionFront ? UIImageOrientationRightMirrored : UIImageOrientationLeft; case UIDeviceOrientationLandscapeRight: return cameraPosition == AVCaptureDevicePositionFront ? UIImageOrientationUpMirrored : UIImageOrientationDown; case UIDeviceOrientationUnknown: case UIDeviceOrientationFaceUp: case UIDeviceOrientationFaceDown: return UIImageOrientationUp; } }
- إنشاء عنصر
VisionImage
باستخدام عنصرCMSampleBuffer
والاتجاه:Swift
let image = VisionImage(buffer: sampleBuffer) image.orientation = imageOrientation( deviceOrientation: UIDevice.current.orientation, cameraPosition: cameraPosition)
Objective-C
MLKVisionImage *image = [[MLKVisionImage alloc] initWithBuffer:sampleBuffer]; image.orientation = [self imageOrientationFromDeviceOrientation:UIDevice.currentDevice.orientation cameraPosition:cameraPosition];
3- تشغيل أداة تصنيف الصور
بشكل غير متزامن:
Swift
imageLabeler.process(image) { labels, error in guard error == nil, let labels = labels, !labels.isEmpty else { // Handle the error. return } // Show results. }
Objective-C
[imageLabeler processImage:image completion:^(NSArray*_Nullable labels, NSError *_Nullable error) { if (labels.count == 0) { // Handle the error. return; } // Show results. }];
بشكل متزامن:
Swift
var labels: [ImageLabel] do { labels = try imageLabeler.results(in: image) } catch let error { // Handle the error. return } // Show results.
Objective-C
NSError *error; NSArray*labels = [imageLabeler resultsInImage:image error:&error]; // Show results or handle the error.
4. الحصول على معلومات عن العناصر المصنّفة
إذا نجحت عملية تصنيف الصور، فسيتم عرض صفيف منImageLabel
يمثل كل ImageLabel
شيئًا
المحدد في الصورة. يمكنك الحصول على الوصف النصي لكل تصنيف (إذا كان متاحًا في
البيانات الوصفية لملف نموذج TensorFlow Lite) ونتيجة الثقة والفهرس.
على سبيل المثال:
Swift
for label in labels { let labelText = label.text let confidence = label.confidence let index = label.index }
Objective-C
for (MLKImageLabel *label in labels) { NSString *labelText = label.text; float confidence = label.confidence; NSInteger index = label.index; }
نصائح لتحسين الأداء في الوقت الفعلي
إذا أردت تصنيف الصور في تطبيق في الوقت الفعلي، فاتبع هذه الإرشادات لتحقيق أفضل معدلات عرض الإطارات:
- لمعالجة إطارات الفيديو، استخدِم واجهة برمجة التطبيقات المتزامنة
results(in:)
الخاصة بأداة الرصد. اتصل لهذه الطريقة منAVCaptureVideoDataOutputSampleBufferDelegate
captureOutput(_, didOutput:from:)
للحصول على النتائج من الفيديو المحدّد بشكل متزامن الإطار. إبقاء جهازAVCaptureVideoDataOutput
alwaysDiscardsLateVideoFrames
كـtrue
لضبط الاتصالات الموجَّهة إلى أداة الرصد. إذا كانت تجربة يصبح إطار الفيديو متاحًا أثناء تشغيل أداة الكشف، وسيتم إسقاطه. - إذا استخدمت مخرجات أداة الكشف لتراكب الرسومات على الصورة المدخلة، والحصول أولاً على النتيجة من ML Kit، ثم عرض الصورة وتراكبها في خطوة واحدة. ومن خلال القيام بذلك، يمكنك العرض على سطح الشاشة مرة واحدة فقط لكل إطار إدخال تمت معالجته. راجع updatePreviewOverlayViewWithLastFrame في عينة البدء السريع لأدوات تعلُّم الآلة كمثال.