אתה יכול להשתמש ML Kit כדי לזהות ולעקוב אחר אובייקטים על פני פריימים של וידאו.
כאשר אתה עובר תמונות ML Kit, ML Kit מחזיר, עבור כל תמונה, רשימה של עד חמישה אובייקטים שזוהו ומיקומם בתמונה. בעת זיהוי אובייקטים בזרמי וידאו, לכל אובייקט יש מזהה שבו אתה יכול להשתמש כדי לעקוב אחר האובייקט על פני תמונות. אתה יכול גם לאפשר סיווג אובייקט גס באופן אופציונלי, אשר מסמן אובייקטים עם תיאורי קטגוריות רחבים.
לפני שאתה מתחיל
- אם עדיין לא הוספת את Firebase לאפליקציה שלך, עשה זאת על ידי ביצוע השלבים במדריך לתחילת העבודה .
- כלול את ספריות ML Kit ב-Podfile שלך:
pod 'Firebase/MLVision', '6.25.0' pod 'Firebase/MLVisionObjectDetection', '6.25.0'
לאחר שתתקין או תעדכן את ה-Pods של הפרויקט שלך, הקפד לפתוח את פרויקט Xcode שלך באמצעות.xcworkspace
שלו. - באפליקציה שלך, ייבא את Firebase:
מָהִיר
import Firebase
Objective-C
@import Firebase;
1. הגדר את גלאי האובייקטים
כדי להתחיל לזהות ולעקוב אחר אובייקטים, תחילה צור מופע של VisionObjectDetector
, אופציונלי לציין את כל הגדרות הגלאי שברצונך לשנות מברירת המחדל.
הגדר את גלאי האובייקטים למקרה השימוש שלך עם אובייקט
VisionObjectDetectorOptions
. אתה יכול לשנות את ההגדרות הבאות:הגדרות גלאי אובייקטים מצב זיהוי .stream
(ברירת מחדל) |.singleImage
במצב זרם (ברירת מחדל), גלאי האובייקט פועל עם זמן אחזור נמוך מאוד, אך עלול להפיק תוצאות לא שלמות (כגון תיבות תוחמות או קטגוריה לא מוגדרת) בכמה הפעלות ראשונות של הגלאי. כמו כן, במצב זרם, הגלאי מקצה מזהי מעקב לאובייקטים, שבהם אתה יכול להשתמש כדי לעקוב אחר אובייקטים על פני מסגרות. השתמש במצב זה כאשר אתה רוצה לעקוב אחר אובייקטים, או כאשר זמן אחזור נמוך חשוב, כגון בעת עיבוד זרמי וידאו בזמן אמת.
במצב תמונה בודדת, גלאי האובייקטים ממתין עד שתיבה התוחמת של אובייקט מזוהה וקטגוריית (אם הפעלת סיווג) זמינות לפני החזרת תוצאה. כתוצאה מכך, זמן השהייה לזיהוי עשוי להיות גבוה יותר. כמו כן, במצב תמונה בודדת, מזהי מעקב אינם מוקצים. השתמש במצב זה אם זמן האחזור אינו קריטי ואתה לא רוצה להתמודד עם תוצאות חלקיות.
זיהוי ומעקב אחר אובייקטים מרובים false
(ברירת מחדל) |true
האם לזהות ולעקוב אחר עד חמישה אובייקטים או רק האובייקט הבולט ביותר (ברירת מחדל).
סיווג חפצים false
(ברירת מחדל) |true
האם לסווג אובייקטים שזוהו לקטגוריות גסות או לא. כאשר מופעל, גלאי האובייקטים מסווג אובייקטים לקטגוריות הבאות: מוצרי אופנה, מזון, מוצרים לבית, מקומות, צמחים ולא ידועים.
ממשק ה-API לזיהוי ומעקב אובייקטים מותאם לשני מקרי שימוש הליבה האלה:
- זיהוי ומעקב בזמן אמת אחר האובייקט הבולט ביותר בעינית המצלמה
- זיהוי של מספר עצמים בתמונה סטטית
כדי להגדיר את ה-API עבור מקרי שימוש אלה:
מָהִיר
// Live detection and tracking let options = VisionObjectDetectorOptions() options.detectorMode = .stream options.shouldEnableMultipleObjects = false options.shouldEnableClassification = true // Optional // Multiple object detection in static images let options = VisionObjectDetectorOptions() options.detectorMode = .singleImage options.shouldEnableMultipleObjects = true options.shouldEnableClassification = true // Optional
Objective-C
// Live detection and tracking FIRVisionObjectDetectorOptions *options = [[FIRVisionObjectDetectorOptions alloc] init]; options.detectorMode = FIRVisionObjectDetectorModeStream; options.shouldEnableMultipleObjects = NO; options.shouldEnableClassification = YES; // Optional // Multiple object detection in static images FIRVisionObjectDetectorOptions *options = [[FIRVisionObjectDetectorOptions alloc] init]; options.detectorMode = FIRVisionObjectDetectorModeSingleImage; options.shouldEnableMultipleObjects = YES; options.shouldEnableClassification = YES; // Optional
קבל מופע של
FirebaseVisionObjectDetector
:מָהִיר
let objectDetector = Vision.vision().objectDetector() // Or, to change the default settings: let objectDetector = Vision.vision().objectDetector(options: options)
Objective-C
FIRVisionObjectDetector *objectDetector = [[FIRVision vision] objectDetector]; // Or, to change the default settings: FIRVisionObjectDetector *objectDetector = [[FIRVision vision] objectDetectorWithOptions:options];
2. הפעל את גלאי האובייקטים
כדי לזהות ולעקוב אחר אובייקטים, בצע את הפעולות הבאות עבור כל תמונה או פריים של וידאו. אם הפעלת את מצב הזרם, עליך ליצור אובייקטים של VisionImage
מ- CMSampleBufferRef
s.
צור אובייקט
VisionImage
באמצעותUIImage
אוCMSampleBufferRef
.כדי להשתמש
UIImage
:- במידת הצורך, סובב את התמונה כך
imageOrientation
שלה יהיה.up
. - צור אובייקט
VisionImage
באמצעותUIImage
המסובב כהלכה. אל תציין מטא נתונים כלשהם של סיבוב - יש להשתמש בערך ברירת המחדל,.topLeft
.מָהִיר
let image = VisionImage(image: uiImage)
Objective-C
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 } }
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; } }
לאחר מכן, צור את אובייקט המטא נתונים:
מָהִיר
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
והמטא נתונים של הסיבוב:מָהִיר
let image = VisionImage(buffer: sampleBuffer) image.metadata = metadata
Objective-C
FIRVisionImage *image = [[FIRVisionImage alloc] initWithBuffer:sampleBuffer]; image.metadata = metadata;
- במידת הצורך, סובב את התמונה כך
העבר את ה-
VisionImage
לאחת משיטות עיבוד התמונה של גלאי האובייקטים. אתה יכול להשתמש בשיטת ה-proces asynchronousprocess(image:)
או בשיטת synchronousresults()
.כדי לזהות אובייקטים באופן אסינכרוני:
מָהִיר
objectDetector.process(image) { detectedObjects, error in guard error == nil else { // Error. return } guard let detectedObjects = detectedObjects, !detectedObjects.isEmpty else { // No objects detected. return } // Success. Get object info here. // ... }
Objective-C
[objectDetector processImage:image completion:^(NSArray<FIRVisionObject *> * _Nullable objects, NSError * _Nullable error) { if (error == nil) { return; } if (objects == nil | objects.count == 0) { // No objects detected. return; } // Success. Get object info here. // ... }];
כדי לזהות אובייקטים באופן סינכרוני:
מָהִיר
var results: [VisionObject]? = nil do { results = try objectDetector.results(in: image) } catch let error { print("Failed to detect object with error: \(error.localizedDescription).") return } guard let detectedObjects = results, !detectedObjects.isEmpty else { print("Object detector returned no results.") return } // ...
Objective-C
NSError *error; NSArray<FIRVisionObject *> *objects = [objectDetector resultsInImage:image error:&error]; if (error == nil) { return; } if (objects == nil | objects.count == 0) { // No objects detected. return; } // Success. Get object info here. // ...
אם הקריאה למעבד התמונה מצליחה, הוא מעביר רשימה של
VisionObject
s למטפל ההשלמה או מחזיר את הרשימה, תלוי אם קראת לשיטה האסינכרונית או הסינכרונית.כל
VisionObject
מכיל את המאפיינים הבאים:frame
CGRect
המציין את מיקום האובייקט בתמונה.trackingID
מספר שלם המזהה את האובייקט על פני תמונות. אפס במצב תמונה בודדת. classificationCategory
הקטגוריה הגסה של האובייקט. אם לגלאי האובייקטים אין סיווג מופעל, זה תמיד .unknown
.confidence
ערך הביטחון של סיווג האובייקטים. אם לגלאי האובייקטים אין סיווג מופעל, או שהאובייקט מסווג כלא ידוע, זה nil
.מָהִיר
// detectedObjects contains one item if multiple object detection wasn't enabled. for obj in detectedObjects { let bounds = obj.frame let id = obj.trackingID // If classification was enabled: let category = obj.classificationCategory let confidence = obj.confidence }
Objective-C
// The list of detected objects contains one item if multiple // object detection wasn't enabled. for (FIRVisionObject *obj in objects) { CGRect bounds = obj.frame; if (obj.trackingID) { NSInteger id = obj.trackingID.integerValue; } // If classification was enabled: FIRVisionObjectCategory category = obj.classificationCategory; float confidence = obj.confidence.floatValue; }
שיפור השימושיות והביצועים
לחוויית המשתמש הטובה ביותר, פעל לפי ההנחיות הבאות באפליקציה שלך:
- זיהוי אובייקט מוצלח תלוי במורכבות החזותית של האובייקט. אובייקטים עם מספר קטן של תכונות ויזואליות עשויים להזדקק לתפוס חלק גדול יותר מהתמונה כדי להיות מזוהה. עליך לספק למשתמשים הנחיות לגבי לכידת קלט שעובדת היטב עם סוג האובייקטים שאתה רוצה לזהות.
- בעת שימוש בסיווג, אם ברצונך לזהות אובייקטים שאינם נכנסים בצורה נקייה לקטגוריות הנתמכות, יישם טיפול מיוחד עבור אובייקטים לא ידועים.
כמו כן, בדוק את [ML Kit Material Design showcase app][showcase-link]{: .external } ואת אוסף התכונות של Material Design Patterns for Machine Learning .
בעת שימוש במצב סטרימינג באפליקציה בזמן אמת, עקוב אחר ההנחיות הבאות כדי להשיג את קצבי המסגרות הטובים ביותר:
אל תשתמש בזיהוי אובייקטים מרובים במצב סטרימינג, מכיוון שרוב המכשירים לא יוכלו לייצר קצבי פריימים נאותים.
השבת את הסיווג אם אינך זקוק לו.
- מצערת קוראת לגלאי. אם מסגרת וידאו חדשה הופכת לזמינה בזמן שהגלאי פועל, שחרר את המסגרת.
- אם אתה משתמש בפלט של הגלאי כדי לשכב גרפיקה על תמונת הקלט, תחילה קבל את התוצאה מ-ML Kit, ולאחר מכן עבד את התמונה ואת שכבת העל בצעד אחד. על ידי כך, אתה מעבד למשטח התצוגה רק פעם אחת עבור כל מסגרת קלט. ראה את המחלקות previewOverlayView ו- FIRDetectionOverlayView באפליקציה לדוגמה לראווה לדוגמא.