אפשר להשתמש ב-Firebase ML כדי לתייג אובייקטים שזוהו בתמונה. בסקירה הכללית מפורט מידע על התכונות של ה-API הזה.
לפני שמתחילים
-
אם עדיין לא הוספתם את Firebase לאפליקציה, עליכם לפעול לפי השלבים שמפורטים במדריך לתחילת העבודה.
- ב-Xcode, כשפרויקט האפליקציה פתוח, עוברים אל קובץ > הוספת חבילות.
- כשמופיעה בקשה, מוסיפים את המאגר של Firebase SDK לפלטפורמות של Apple:
- בוחרים את הספרייה Firebase ML.
- מוסיפים את הדגל
-ObjC
לקטע Other Linker Flags (דגלים אחרים של קישור) בהגדרות ה-build של היעד. - בסיום, Xcode יתחיל לפתור את יחסי התלות ולהוריד אותם באופן אוטומטי ברקע.
- באפליקציה, מייבאים את Firebase:
import FirebaseMLModelDownloader
@import FirebaseMLModelDownloader;
-
אם עדיין לא הפעלתם ממשקי API מבוססי-Cloud בפרויקט, עליכם לעשות זאת עכשיו:
- פותחים את דף ממשקי ה-API של Firebase ML במסוף Firebase.
-
אם עדיין לא שדרגתם את הפרויקט לתוכנית התמחור Blaze, לוחצים על שדרוג כדי לעשות זאת. (הבקשה לשדרוג תוצג רק אם הפרויקט לא בתוכנית Blaze).
רק בפרויקטים ברמת Blaze אפשר להשתמש בממשקי API מבוססי-Cloud.
- אם ממשקי ה-API מבוססי-הענן עדיין לא מופעלים, לוחצים על Enable Cloud-based APIs.
שימוש ב-Swift Package Manager כדי להתקין ולנהל יחסי תלות ב-Firebase.
https://github.com/firebase/firebase-ios-sdk.git
בשלב הבא מבצעים כמה הגדרות באפליקציה:
עכשיו אתם מוכנים לתייג תמונות.
1. הכנת קובץ הקלט
יוצרים אובייקט VisionImage
באמצעות UIImage
או CMSampleBufferRef
.
כדי להשתמש ב-UIImage
:
- אם צריך, מסובבים את התמונה כך שהנכס
imageOrientation
יהיה.up
. - יוצרים אובייקט
VisionImage
באמצעותUIImage
שסובב בצורה נכונה. אין לציין מטא-נתונים של סיבוב – צריך להשתמש בערך ברירת המחדל,.topLeft
.let image = VisionImage(image: uiImage)
FIRVisionImage *image = [[FIRVisionImage alloc] initWithImage:uiImage];
כדי להשתמש ב-CMSampleBufferRef
:
-
יוצרים אובייקט
VisionImageMetadata
שמציין את הכיוון של נתוני התמונה שמכיל מאגר ה-CMSampleBufferRef
.כדי לקבל את כיוון התמונה:
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 } }
- (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; } }
לאחר מכן יוצרים את אובייקט המטא-נתונים:
let cameraPosition = AVCaptureDevice.Position.back // Set to the capture device you used. let metadata = VisionImageMetadata() metadata.orientation = imageOrientation( deviceOrientation: UIDevice.current.orientation, cameraPosition: cameraPosition )
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
והמטא-נתונים של הסיבוב:let image = VisionImage(buffer: sampleBuffer) image.metadata = metadata
FIRVisionImage *image = [[FIRVisionImage alloc] initWithBuffer:sampleBuffer]; image.metadata = metadata;
2. הגדרה והרצה של הכלי לתיוג תמונות
כדי לתייג אובייקטים בתמונה, מעבירים את האובייקטVisionImage
לשיטה processImage()
של VisionImageLabeler
.
קודם כל, מקבלים מכונה של
VisionImageLabeler
:let labeler = Vision.vision().cloudImageLabeler() // Or, to set the minimum confidence required: // let options = VisionCloudImageLabelerOptions() // options.confidenceThreshold = 0.7 // let labeler = Vision.vision().cloudImageLabeler(options: options)
FIRVisionImageLabeler *labeler = [[FIRVision vision] cloudImageLabeler]; // Or, to set the minimum confidence required: // FIRVisionCloudImageLabelerOptions *options = // [[FIRVisionCloudImageLabelerOptions alloc] init]; // options.confidenceThreshold = 0.7; // FIRVisionImageLabeler *labeler = // [[FIRVision vision] cloudImageLabelerWithOptions:options];
לאחר מכן, מעבירים את התמונה לשיטה
processImage()
:labeler.process(image) { labels, error in guard error == nil, let labels = labels else { return } // Task succeeded. // ... }
[labeler processImage:image completion:^(NSArray<FIRVisionImageLabel *> *_Nullable labels, NSError *_Nullable error) { if (error != nil) { return; } // Task succeeded. // ... }];
3. אחזור מידע על אובייקטים מתויגים
אם התיוג של התמונה יצליח, מערך של אובייקטים מסוגVisionImageLabel
יועבר למטפל השלמות. מכל אובייקט אפשר לקבל מידע על מאפיין שזוהה בתמונה.
לדוגמה:
for label in labels {
let labelText = label.text
let entityId = label.entityID
let confidence = label.confidence
}
for (FIRVisionImageLabel *label in labels) {
NSString *labelText = label.text;
NSString *entityId = label.entityID;
NSNumber *confidence = label.confidence;
}
השלבים הבאים
- לפני פריסת אפליקציה שמשתמשת ב-Cloud API בסביבת הייצור, כדאי לבצע כמה פעולות נוספות כדי למנוע גישה לא מורשית ל-API ולצמצם את ההשפעה שלה.