Join us for Firebase Summit on November 10, 2021. Tune in to learn how Firebase can help you accelerate app development, release with confidence, and scale with ease. Register

זיהוי ועקוב אחר אובייקטים באמצעות ערכת ML ב- iOS

תוכל להשתמש בערכת ML לאיתור ומעקב אחר אובייקטים במסגרות וידאו.

כאשר אתה מעביר תמונות ML Kit, ML Kit מחזיר, עבור כל תמונה, רשימה של עד חמישה אובייקטים שזוהו ומיקומם בתמונה. בעת זיהוי אובייקטים בזרמי וידאו, לכל אובייקט יש מזהה שניתן להשתמש בו כדי לעקוב אחר האובייקט בין תמונות. באפשרותך גם להפעיל סיווג אובייקטים גס, המסמן אובייקטים עם תיאורי קטגוריות רחבות.

לפני שאתה מתחיל

  1. אם לא כבר הוסיף Firebase באפליקציה, לעשות זאת על ידי ביצוע השלבים במדריך להפעלה .
  2. כלול את הספריות קיט ML ב Podfile שלך:
    pod 'Firebase/MLVision', '6.25.0'
    pod 'Firebase/MLVisionObjectDetection', '6.25.0'
    
    לאחר להתקין או לעדכן שקיקים של הפרויקט שלך, להיות בטוח כדי לפתוח פרויקט Xcode שלך באמצעות שלה .xcworkspace .
  3. באפליקציה שלך, ייבא את Firebase:

    מָהִיר

    import Firebase

    Objective-C

    @import Firebase;

1. הגדר את גלאי האובייקטים

כדי להתחיל באיתור ומעקב אחר אובייקטים, ראשון ליצור מופע של VisionObjectDetector , המפרט את כול הגדרות גלאי אופציונאלי ברצונך לשנות מברירת המחדל.

  1. הגדר את גלאי אובייקט עבור המקרה שלכם עם 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
    
  2. קבל מופע של 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 ים.

  1. צור VisionImage אובייקט באמצעות UIImage או CMSampleBufferRef .

    כדי להשתמש UIImage :

    1. במידת הצורך, לסובב את התמונה כך שלה imageOrientation הנכס הוא .up .
    2. צור VisionImage אובייקט באמצעות כראוי-המסובב UIImage . לא ציין סיבוב מטה-ערך ברירת המחדל, .topLeft , חייב לשמש.

      מָהִיר

      let image = VisionImage(image: uiImage)

      Objective-C

      FIRVisionImage *image = [[FIRVisionImage alloc] initWithImage:uiImage];

    כדי להשתמש CMSampleBufferRef :

    1. צור 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];
    2. צור VisionImage אובייקט באמצעות CMSampleBufferRef האובייקט ואת מטה סיבוב:

      מָהִיר

      let image = VisionImage(buffer: sampleBuffer)
      image.metadata = metadata

      Objective-C

      FIRVisionImage *image = [[FIRVisionImage alloc] initWithBuffer:sampleBuffer];
      image.metadata = metadata;
  2. תעביר את VisionImage לאחת שיטות עיבוד תמונת האובייקט של הגלאי. אתה יכול גם להשתמש אסינכרוני process(image:) שיטה או סינכרוני results() שיטה.

    כדי לזהות אובייקטים באופן אסינכרוני:

    מָהִיר

    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.
    // ...
    
  3. אם השיחה למעבד התמונה תצליח, הוא גם עובר רשימה VisionObject הים למטפל ההשלמה או מחזיר את הרשימה, תלוי אם קראת את שיטת אסינכרוני או סינכרוני.

    כל 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 קיט חומר עיצוב חלון ראווה אפליקציות] [ראווה-link] {: .external} ואת עיצוב חומר דפוסי עבור תכונות המכונה המופעל למידה אוסף.

בעת שימוש במצב סטרימינג ביישום בזמן אמת, עקוב אחר ההנחיות הבאות כדי להשיג את מספר המסגרות הטוב ביותר:

  • אל תשתמש בזיהוי אובייקטים מרובים במצב סטרימינג, מכיוון שרוב המכשירים לא יוכלו לייצר מספר פריימים מתאים.

  • השבת את הסיווג אם אינך זקוק לו.

  • מצערת מצערת לגלאי. אם מסגרת וידאו חדשה הופכת לזמינה בזמן שהגלאי פועל, השמט את המסגרת.
  • אם אתה משתמש בפלט הגלאי על מנת לכסות גרפיקה על תמונת הקלט, תחילה קבל את התוצאה מ- ML Kit, ולאחר מכן עיבד את התמונה ואת שכבת העל בשלב אחד. בכך אתה מעבד למשטח התצוגה רק פעם אחת עבור כל מסגרת קלט. עיין previewOverlayView ו FIRDetectionOverlayView כיתות ביישום מדגם ראווה עבור דוגמה.