אחרי אימון המודל באמצעות AutoML Vision Edge, אפשר להשתמש בו באפליקציה כדי להוסיף תוויות תמונות.
לפני שמתחילים
- אם עדיין לא הוספתם את Firebase לאפליקציה, צריך לבצע את הפעולות הבאות במדריך לתחילת העבודה.
- כוללים את ספריות ML Kit ב-Podfile:
אחרי שמתקינים או מעדכנים את קבוצות ה-Pod של הפרויקט, חשוב לפתוח את ה-Xcode באמצעות ה-pod 'Firebase/MLVision', '6.25.0' pod 'Firebase/MLVisionAutoML', '6.25.0'
.xcworkspace
שלו. - מייבאים את Firebase לאפליקציה:
Swift
import Firebase
Objective-C
@import Firebase;
1. טעינת המודל
ML Kit מפעיל את המודלים שנוצרו באמצעות AutoML במכשיר. אבל אפשר להגדיר ML Kit כדי לטעון את המודל מרחוק מ-Firebase, אחסון מקומי, או את שניהם.
אירוח המודל ב-Firebase יאפשר לכם לעדכן את המודל בלי לפרסם אותו גרסת אפליקציה חדשה, ואפשר להשתמש ב-Remote Config וב-A/B Testing כדי להציג מודלים שונים באופן דינמי לקבוצות שונות של משתמשים.
אם תבחרו לספק את המודל רק על ידי אירוח שלו ב-Firebase, ולא ב-Firebase לצרף אותו לאפליקציה שלך, אפשר להקטין את גודל ההורדה הראשוני של האפליקציה. עם זאת, חשוב לזכור שאם המודל לא נכלל בחבילה עם האפליקציה שלכם, שקשורה למודלים לא יהיו זמינים עד שהאפליקציה תוריד את בפעם הראשונה.
כשמצרפים את המודל לאפליקציה, אפשר לוודא שתכונות ה-ML של האפליקציה ימשיכו לפעול גם כשהמודל שמתארח ב-Firebase לא זמין.
הגדרת מקור מודל שמתארח ב-Firebase
כדי להשתמש במודל שמתארח מרחוק, צריך ליצור אובייקט AutoMLRemoteModel
,
שמציין את השם שהקציתם למודל כשפרסמתם אותו:
Swift
let remoteModel = AutoMLRemoteModel(
name: "your_remote_model" // The name you assigned in the Firebase console.
)
Objective-C
FIRAutoMLRemoteModel *remoteModel = [[FIRAutoMLRemoteModel 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
FIRModelDownloadConditions *downloadConditions =
[[FIRModelDownloadConditions alloc] initWithAllowsCellularAccess:YES
allowsBackgroundDownloading:YES];
NSProgress *downloadProgress =
[[FIRModelManager modelManager] downloadRemoteModel:remoteModel
conditions:downloadConditions];
באפליקציות רבות, משימה ההורדה מתחילה בקוד האיניציאליזציה, אבל אפשר לעשות זאת בכל שלב לפני שמשתמשים במודל.
הגדרת מקור למודל מקומי
כדי לצרף את המודל לאפליקציה:
- חילוץ המודל והמטא-נתונים שלו מארכיון ה-ZIP שהורדתם
ממסוף Firebase לתיקייה:
כל שלושת הקבצים חייבים להיות באותה תיקייה. מומלץ להשתמש בקבצים בתור שהורדתם אותם, מבלי לבצע שינויים (כולל שמות הקבצים).your_model_directory |____dict.txt |____manifest.json |____model.tflite
- מעתיקים את התיקייה לפרויקט Xcode ומקפידים לבחור לשם כך, צרו הפניות לתיקיות. קובץ המודל והמטא-נתונים ייכללו ב-App Bundle ויהיו זמינים ל-ML Kit.
- יצירת אובייקט
AutoMLLocalModel
, ולציין את הנתיב למניפסט של המודל file:Swift
guard let manifestPath = Bundle.main.path( forResource: "manifest", ofType: "json", inDirectory: "your_model_directory" ) else { return true } let localModel = AutoMLLocalModel(manifestPath: manifestPath)
Objective-C
NSString *manifestPath = [NSBundle.mainBundle pathForResource:@"manifest" ofType:@"json" inDirectory:@"your_model_directory"]; FIRAutoMLLocalModel *localModel = [[FIRAutoMLLocalModel alloc] initWithManifestPath:manifestPath];
יצירת מתייג לתמונה מהמודל
אחרי שמגדירים את מקורות המודלים, צריך ליצור אובייקט VisionImageLabeler
מאחד מהם.
אם יש לכם רק מודל באריזה מקומית, פשוט יוצרים מתייגים
אובייקט אחד (AutoMLLocalModel
) והגדרת הסף הרצוי של ציון הסמך
לפי הצורך (ראו הערכת המודל):
Swift
let options = VisionOnDeviceAutoMLImageLabelerOptions(localModel: localModel)
options.confidenceThreshold = 0 // Evaluate your model in the Firebase console
// to determine an appropriate value.
let labeler = Vision.vision().onDeviceAutoMLImageLabeler(options: options)
Objective-C
FIRVisionOnDeviceAutoMLImageLabelerOptions *options =
[[FIRVisionOnDeviceAutoMLImageLabelerOptions alloc] initWithLocalModel:localModel];
options.confidenceThreshold = 0; // Evaluate your model in the Firebase console
// to determine an appropriate value.
FIRVisionImageLabeler *labeler =
[[FIRVision vision] onDeviceAutoMLImageLabelerWithOptions:options];
אם יש לכם מודל שמתארח מרחוק, תצטרכו לוודא שהוא הוריד לפני שתפעילו אותו. אפשר לבדוק את סטטוס ההורדה של המודל
באמצעות השיטה isModelDownloaded(remoteModel:)
של מנהל המודלים.
למרות שצריך לאשר זאת רק לפני הפעלת המתייג, אם
יש להם גם מודל שמתארח מרחוק וגם מודל בחבילות מקומיות, זה עלול ליצור
לבצע את הבדיקה הזו כשמממשים את הפקודה VisionImageLabeler
: create
מתייג מהמודל המרוחק אם הוא הוריד אותו,
אחרת.
Swift
var options: VisionOnDeviceAutoMLImageLabelerOptions?
if (ModelManager.modelManager().isModelDownloaded(remoteModel)) {
options = VisionOnDeviceAutoMLImageLabelerOptions(remoteModel: remoteModel)
} else {
options = VisionOnDeviceAutoMLImageLabelerOptions(localModel: localModel)
}
options.confidenceThreshold = 0 // Evaluate your model in the Firebase console
// to determine an appropriate value.
let labeler = Vision.vision().onDeviceAutoMLImageLabeler(options: options)
Objective-C
VisionOnDeviceAutoMLImageLabelerOptions *options;
if ([[FIRModelManager modelManager] isModelDownloaded:remoteModel]) {
options = [[FIRVisionOnDeviceAutoMLImageLabelerOptions alloc] initWithRemoteModel:remoteModel];
} else {
options = [[FIRVisionOnDeviceAutoMLImageLabelerOptions alloc] initWithLocalModel:localModel];
}
options.confidenceThreshold = 0.0f; // Evaluate your model in the Firebase console
// to determine an appropriate value.
FIRVisionImageLabeler *labeler = [[FIRVision vision] onDeviceAutoMLImageLabelerWithOptions:options];
אם יש לכם רק מודל שמתארח מרחוק, עליכם להשבית את הפונקציונליות שקשורה למודל – לדוגמה, להפוך חלק מממשק המשתמש לאפור או להסתיר אותו – עד שתאשרו שהמודל הוריד.
כדי לראות את סטטוס ההורדה של המודל, אפשר לצרף תצפיתנים לברירת המחדל
מרכז ההתראות. חשוב להשתמש בהתייחסות חלשה אל self
בצופה
מכיוון שהורדות עשויות להימשך זמן מה, ואובייקט המקור יכול להיות
בחינם עד לסיום ההורדה. לדוגמה:
Swift
NotificationCenter.default.addObserver( forName: .firebaseMLModelDownloadDidSucceed, 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: .firebaseMLModelDownloadDidFail, 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:FIRModelDownloadDidSucceedNotification object:nil queue:nil usingBlock:^(NSNotification *_Nonnull note) { if (weakSelf == nil | note.userInfo == nil) { return; } __strong typeof(self) strongSelf = weakSelf; FIRRemoteModel *model = note.userInfo[FIRModelDownloadUserInfoKeyRemoteModel]; if ([model.name isEqualToString:@"your_remote_model"]) { // The model was downloaded and is available on the device } }]; [NSNotificationCenter.defaultCenter addObserverForName:FIRModelDownloadDidFailNotification object:nil queue:nil usingBlock:^(NSNotification *_Nonnull note) { if (weakSelf == nil | note.userInfo == nil) { return; } __strong typeof(self) strongSelf = weakSelf; NSError *error = note.userInfo[FIRModelDownloadUserInfoKeyError]; }];
2. הכנת תמונת הקלט
לאחר מכן, לכל תמונה שרוצים לתייג, יוצרים אובייקט VisionImage
באמצעות אחת מהאפשרויות שמתוארות בקטע הזה ומעבירים אותו למכונה של VisionImageLabeler
(כפי שמתואר בקטע הבא).
יוצרים אובייקט VisionImage
באמצעות UIImage
או CMSampleBufferRef
.
כדי להשתמש ב-UIImage
:
- במקרה הצורך, מסובבים את התמונה כך ש-
imageOrientation
הוא.up
. - יצירת אובייקט
VisionImage
באמצעות סיבוב נכוןUIImage
. אל תציינו מטא-נתונים של סבב, ברירת המחדל יש להשתמש בערך.topLeft
.Swift
let image = VisionImage(image: uiImage)
Objective-C
FIRVisionImage *image = [[FIRVisionImage alloc] initWithImage:uiImage];
כדי להשתמש ב-CMSampleBufferRef
:
-
יוצרים אובייקט
VisionImageMetadata
שמציין את של נתוני התמונה שכלולים מאגר נתונים זמני שלCMSampleBufferRef
.כדי לקבל את כיוון התמונה:
Swift
func imageOrientation( deviceOrientation: UIDeviceOrientation, cameraPosition: AVCaptureDevice.Position ) -> VisionDetectorImageOrientation { switch deviceOrientation { case .portrait: return cameraPosition == .front ? .leftTop : .rightTop case .landscapeLeft: return cameraPosition == .front ? .bottomLeft : .topLeft case .portraitUpsideDown: return cameraPosition == .front ? .rightBottom : .leftBottom case .landscapeRight: return cameraPosition == .front ? .topRight : .bottomRight case .faceDown, .faceUp, .unknown: return .leftTop } }
Objective-C
- (FIRVisionDetectorImageOrientation) imageOrientationFromDeviceOrientation:(UIDeviceOrientation)deviceOrientation cameraPosition:(AVCaptureDevicePosition)cameraPosition { switch (deviceOrientation) { case UIDeviceOrientationPortrait: if (cameraPosition == AVCaptureDevicePositionFront) { return FIRVisionDetectorImageOrientationLeftTop; } else { return FIRVisionDetectorImageOrientationRightTop; } case UIDeviceOrientationLandscapeLeft: if (cameraPosition == AVCaptureDevicePositionFront) { return FIRVisionDetectorImageOrientationBottomLeft; } else { return FIRVisionDetectorImageOrientationTopLeft; } case UIDeviceOrientationPortraitUpsideDown: if (cameraPosition == AVCaptureDevicePositionFront) { return FIRVisionDetectorImageOrientationRightBottom; } else { return FIRVisionDetectorImageOrientationLeftBottom; } case UIDeviceOrientationLandscapeRight: if (cameraPosition == AVCaptureDevicePositionFront) { return FIRVisionDetectorImageOrientationTopRight; } else { return FIRVisionDetectorImageOrientationBottomRight; } default: return FIRVisionDetectorImageOrientationTopLeft; } }
לאחר מכן, יוצרים את אובייקט המטא-נתונים:
Swift
let cameraPosition = AVCaptureDevice.Position.back // Set to the capture device you used. let metadata = VisionImageMetadata() metadata.orientation = imageOrientation( deviceOrientation: UIDevice.current.orientation, cameraPosition: cameraPosition )
Objective-C
FIRVisionImageMetadata *metadata = [[FIRVisionImageMetadata alloc] init]; AVCaptureDevicePosition cameraPosition = AVCaptureDevicePositionBack; // Set to the capture device you used. metadata.orientation = [self imageOrientationFromDeviceOrientation:UIDevice.currentDevice.orientation cameraPosition:cameraPosition];
- יוצרים אובייקט
VisionImage
באמצעות אובייקטCMSampleBufferRef
והמטא-נתונים של הסבב:Swift
let image = VisionImage(buffer: sampleBuffer) image.metadata = metadata
Objective-C
FIRVisionImage *image = [[FIRVisionImage alloc] initWithBuffer:sampleBuffer]; image.metadata = metadata;
3. הפעלה של מתייג התמונה
כדי להוסיף תוויות לאובייקטים בתמונה, צריך להעביר את האובייקט VisionImage
אל
ה-method process()
של VisionImageLabeler
:
Swift
labeler.process(image) { labels, error in
guard error == nil, let labels = labels else { return }
// Task succeeded.
// ...
}
Objective-C
[labeler
processImage:image
completion:^(NSArray<FIRVisionImageLabel *> *_Nullable labels, NSError *_Nullable error) {
if (error != nil || labels == nil) {
return;
}
// Task succeeded.
// ...
}];
אם התיוג של התמונה יסתיים בהצלחה, מערך של אובייקטים מסוג VisionImageLabel
יועבר למטפל השלמות. מכל אובייקט אפשר לקבל מידע על מאפיין שזוהה בתמונה.
לדוגמה:
Swift
for label in labels {
let labelText = label.text
let confidence = label.confidence
}
Objective-C
for (FIRVisionImageLabel *label in labels) {
NSString *labelText = label.text;
NSNumber *confidence = label.confidence;
}
טיפים לשיפור הביצועים בזמן אמת
- ויסות נתונים (throttle) קריאות לגלאי. אם פריים חדש בסרטון הופך בזמן שהגלאי פועל, משחררים את הפריים.
- אם משתמשים בפלט של הגלאי כדי להציג גרפיקה בשכבת-על מקבלים קודם את התוצאה מ-ML Kit ואז מעבדים את התמונה וליצור שכבת-על בשלב אחד. כך תוכלו להציג את משטח המסך פעם אחת בלבד לכל מסגרת קלט. אפשר לעיין ב-previewOverlayView ו-FIRDetectionOverlayView באפליקציה לדוגמה של Showcase.