לאחר שתאמן את הדגם שלך באמצעות AutoML Vision Edge , תוכל להשתמש בו באפליקציה שלך כדי לתייג תמונות.
ישנן שתי דרכים לשלב דגמים שהוכשרו מ-AutoML Vision Edge. אתה יכול לאגד את המודל על ידי העתקת קבצי המודל לפרויקט Xcode שלך, או שאתה יכול להוריד אותו באופן דינמי מ-Firebase.
אפשרויות חבילת דגמים | |
---|---|
מאגד באפליקציה שלך |
|
מתארח עם Firebase |
|
לפני שאתה מתחיל
כלול את ספריות ML Kit ב-Podfile שלך:
לאגד דגם עם האפליקציה שלך:
pod 'GoogleMLKit/ImageLabelingCustom'
להורדה דינמית של מודל מ-Firebase, הוסף את התלות
LinkFirebase
:pod 'GoogleMLKit/ImageLabelingCustom' pod 'GoogleMLKit/LinkFirebase'
לאחר התקנת או עדכון Pods של הפרויקט שלך, פתח את פרויקט Xcode שלך באמצעות
.xcworkspace
שלו. ערכת ML נתמכת בגרסת Xcode 12.2 ומעלה.אם ברצונך להוריד דגם , הקפד להוסיף את Firebase לפרויקט האנדרואיד שלך , אם עדיין לא עשית זאת. זה לא נדרש כאשר אתה מצרף את הדגם.
1. טען את הדגם
הגדר מקור דגם מקומי
כדי לאגד את הדגם עם האפליקציה שלך:
חלץ את המודל ואת המטא נתונים שלו מארכיון ה-zip שהורדת ממסוף Firebase לתיקיה:
your_model_directory |____dict.txt |____manifest.json |____model.tflite
כל שלושת הקבצים חייבים להיות באותה תיקיה. אנו ממליצים להשתמש בקבצים כפי שהורדתם אותם, ללא שינוי (כולל שמות הקבצים).
העתק את התיקיה לפרויקט Xcode שלך, הקפד לבחור באפשרות צור הפניות לתיקיות כאשר אתה עושה זאת. קובץ הדגם והמטא נתונים ייכללו ב-App Bundle וזמינים ל-ML Kit.
צור אובייקט
LocalModel
, תוך ציון הנתיב לקובץ המניפסט של המודל:מָהִיר
guard let manifestPath = Bundle.main.path( forResource: "manifest", ofType: "json", inDirectory: "your_model_directory" ) else { return true } let localModel = LocalModel(manifestPath: manifestPath)
Objective-C
NSString *manifestPath = [NSBundle.mainBundle pathForResource:@"manifest" ofType:@"json" inDirectory:@"your_model_directory"]; MLKLocalModel *localModel = [[MLKLocalModel alloc] initWithManifestPath:manifestPath];
הגדר מקור מודל שמתארח ב-Firebase
כדי להשתמש במודל המתארח מרחוק, צור אובייקט CustomRemoteModel
, תוך ציון השם שהקצית למודל כשפרסמת אותו:
מָהִיר
// Initialize the model source with the name you assigned in
// the Firebase console.
let remoteModelSource = FirebaseModelSource(name: "your_remote_model")
let remoteModel = CustomRemoteModel(remoteModelSource: remoteModelSource)
Objective-C
// Initialize the model source with the name you assigned in
// the Firebase console.
MLKFirebaseModelSource *firebaseModelSource =
[[MLKFirebaseModelSource alloc] initWithName:@"your_remote_model"];
MLKCustomRemoteModel *remoteModel =
[[MLKCustomRemoteModel alloc] initWithRemoteModelSource:firebaseModelSource];
לאחר מכן, התחל את משימת הורדת הדגם, תוך ציון התנאים שבהם ברצונך לאפשר הורדה. אם הדגם אינו במכשיר, או אם זמינה גרסה חדשה יותר של הדגם, המשימה תוריד את הדגם באופן אסינכרוני מ-Firebase:
מָהִיר
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] downloadRemoteModel:remoteModel
conditions:downloadConditions];
אפליקציות רבות מתחילות את משימת ההורדה בקוד האתחול שלהן, אך תוכל לעשות זאת בכל שלב לפני שתצטרך להשתמש במודל.
צור תוויות תמונה מהדגם שלך
לאחר שתגדיר את מקורות המודל שלך, צור אובייקט ImageLabeler
מאחד מהם.
אם יש לך רק מודל מקובץ מקומית, פשוט צור תוויות מאובייקט LocalModel
שלך והגדר את סף ציון הביטחון שאתה רוצה לדרוש (ראה הערכת המודל שלך ):
מָהִיר
let options = CustomImageLabelerOptions(localModel: localModel)
options.confidenceThreshold = NSNumber(value: 0.0) // Evaluate your model in the Cloud console
// to determine an appropriate value.
let imageLabeler = ImageLabeler.imageLabeler(options)
Objective-C
CustomImageLabelerOptions *options =
[[CustomImageLabelerOptions alloc] initWithLocalModel:localModel];
options.confidenceThreshold = @(0.0f); // Evaluate your model in the Cloud console
// to determine an appropriate value.
MLKImageLabeler *imageLabeler =
[MLKImageLabeler imageLabelerWithOptions:options];
אם יש לך דגם שמתארח מרחוק, תצטרך לבדוק שהוא הורד לפני שתפעיל אותו. אתה יכול לבדוק את המצב של משימת הורדת המודל באמצעות שיטת isModelDownloaded(remoteModel:)
של מנהל המודלים.
למרות שאתה רק צריך לאשר זאת לפני הפעלת התווית, אם יש לך גם דגם שמתארח מרחוק וגם דגם עם חבילה מקומית, ייתכן שיהיה הגיוני לבצע את הבדיקה הזו בעת הפעלת ה- ImageLabeler
: צור תוויות מהדגם המרוחק אם זה הורד, ומהדגם המקומי אחרת.
מָהִיר
var options: CustomImageLabelerOptions
if (ModelManager.modelManager().isModelDownloaded(remoteModel)) {
options = CustomImageLabelerOptions(remoteModel: remoteModel)
} else {
options = CustomImageLabelerOptions(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
MLKCustomImageLabelerOptions *options;
if ([[MLKModelManager modelManager] isModelDownloaded:remoteModel]) {
options = [[MLKCustomImageLabelerOptions alloc] initWithRemoteModel:remoteModel];
} else {
options = [[MLKCustomImageLabelerOptions alloc] initWithLocalModel:localModel];
}
options.confidenceThreshold = @(0.0f); // Evaluate your model in the Firebase console
// to determine an appropriate value.
MLKImageLabeler *imageLabeler =
[MLKImageLabeler imageLabelerWithOptions:options];
אם יש לך רק דגם שמתארח מרחוק, עליך להשבית את הפונקציונליות הקשורה לדגם - למשל, לאפור או להסתיר חלק מהממשק שלך - עד שתאשר שהדגם הורד.
אתה יכול לקבל את סטטוס הורדת הדגם על ידי צירוף צופים למרכז ההתראות המוגדר כברירת מחדל. הקפד להשתמש בהתייחסות חלשה self
בבלוק הצופה, מכיוון שההורדות יכולות להימשך זמן מה, והאובייקט המקור יכול להשתחרר עד לסיום ההורדה. לדוגמה:
מָהִיר
NotificationCenter.default.addObserver(
forName: .mlkitMLModelDownloadDidSucceed,
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: .mlkitMLModelDownloadDidFail,
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
או CMSampleBufferRef
.
אם אתה משתמש ב- UIImage
, בצע את השלבים הבאים:
- צור אובייקט
VisionImage
עםUIImage
. הקפד לציין את.orientation
הנכון.מָהִיר
let image = VisionImage(image: uiImage) visionImage.orientation = image.imageOrientation
Objective-C
MLKVisionImage *visionImage = [[MLKVisionImage alloc] initWithImage:image]; visionImage.orientation = image.imageOrientation;
אם אתה משתמש ב- CMSampleBufferRef
, בצע את השלבים הבאים:
ציין את הכיוון של נתוני התמונה הכלולים במאגר
CMSampleBufferRef
.כדי לקבל את כיוון התמונה:
מָהִיר
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 position == AVCaptureDevicePositionFront ? UIImageOrientationLeftMirrored : UIImageOrientationRight; case UIDeviceOrientationLandscapeLeft: return position == AVCaptureDevicePositionFront ? UIImageOrientationDownMirrored : UIImageOrientationUp; case UIDeviceOrientationPortraitUpsideDown: return position == AVCaptureDevicePositionFront ? UIImageOrientationRightMirrored : UIImageOrientationLeft; case UIDeviceOrientationLandscapeRight: return position == AVCaptureDevicePositionFront ? UIImageOrientationUpMirrored : UIImageOrientationDown; case UIDeviceOrientationUnknown: case UIDeviceOrientationFaceUp: case UIDeviceOrientationFaceDown: return UIImageOrientationUp; } }
- צור אובייקט
VisionImage
באמצעות האובייקט והכיווןCMSampleBufferRef
:מָהִיר
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. הפעל את תווית התמונות
באופן אסינכרוני:
מָהִיר
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<MLKImageLabel *> *_Nullable labels,
NSError *_Nullable error) {
if (label.count == 0) {
// Handle the error.
return;
}
// Show results.
}];
באופן סינכרוני:
מָהִיר
var labels: [ImageLabel]
do {
labels = try imageLabeler.results(in: image)
} catch let error {
// Handle the error.
return
}
// Show results.
Objective-C
NSError *error;
NSArray<MLKImageLabel *> *labels =
[imageLabeler resultsInImage:image error:&error];
// Show results or handle the error.
4. קבל מידע על אובייקטים מסומנים
אם פעולת תיוג התמונה מצליחה, היא מחזירה מערך של ImageLabel
. כל ImageLabel
מייצג משהו שסומן בתמונה. אתה יכול לקבל את תיאור הטקסט של כל תווית (אם זמין במטא נתונים של קובץ המודל של TensorFlow Lite), ציון ביטחון ואינדקס. לדוגמה:
מָהִיר
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;
}
טיפים לשיפור הביצועים בזמן אמת
אם ברצונך לסמן תמונות ביישום בזמן אמת, פעל לפי ההנחיות הבאות כדי להשיג את קצבי המסגרות הטובים ביותר:
- מצערת קוראת לגלאי. אם מסגרת וידאו חדשה הופכת לזמינה בזמן שהגלאי פועל, שחרר את המסגרת.
- אם אתה משתמש בפלט של הגלאי כדי לשכב על גרפיקה על תמונת הקלט, תחילה קבל את התוצאה, ולאחר מכן עבד את התמונה ואת שכבת העל בצעד אחד. על ידי כך, אתה מעבד למשטח התצוגה רק פעם אחת עבור כל מסגרת קלט. ראה את המחלקות previewOverlayView ו- FIRDetectionOverlayView באפליקציה לדוגמה לראווה לדוגמא.