ตรวจจับและติดตามวัตถุด้วย ML Kit บน iOS

คุณสามารถใช้ ML Kit เพื่อตรวจจับและติดตามวัตถุข้ามเฟรมของวิดีโอได้

เมื่อคุณส่งภาพ ML Kit ML Kit จะส่งกลับรายการวัตถุที่ตรวจพบสูงสุดห้ารายการและตำแหน่งในรูปภาพสำหรับแต่ละภาพ เมื่อตรวจจับวัตถุในสตรีมวิดีโอ วัตถุทุกชิ้นจะมี ID ที่คุณสามารถใช้เพื่อติดตามวัตถุในรูปภาพต่างๆ คุณยังสามารถเลือกเปิดใช้งานการจัดประเภทอ็อบเจ็กต์หยาบ ซึ่งจะติดป้ายอ็อบเจ็กต์ด้วยคำอธิบายหมวดหมู่แบบกว้างๆ

ก่อนที่คุณจะเริ่ม

  1. หากคุณยังไม่ได้เพิ่ม Firebase ลงในแอปของคุณ ให้ทำตามขั้นตอนใน คู่มือการเริ่มต้นใช้งาน
  2. รวมไลบรารี ML Kit ไว้ใน Podfile ของคุณ:
    pod 'Firebase/MLVision', '6.25.0'
    pod 'Firebase/MLVisionObjectDetection', '6.25.0'
    
    หลังจากที่คุณติดตั้งหรืออัปเดต Pod ของโปรเจ็กต์แล้ว อย่าลืมเปิดโปรเจ็กต์ Xcode โดยใช้ .xcworkspace
  3. ในแอปของคุณ ให้นำเข้า Firebase:

    สวิฟท์

    import Firebase

    วัตถุประสงค์-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
    

    วัตถุประสงค์-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)
    

    วัตถุประสงค์-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)

      วัตถุประสงค์-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
          }
      }

      วัตถุประสงค์-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
      )

      วัตถุประสงค์-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

      วัตถุประสงค์-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.
      // ...
    }
    

    วัตถุประสงค์-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
    }
    
    // ...
    

    วัตถุประสงค์-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
    }
    

    วัตถุประสงค์-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][showcase-link]{: .external } และ รูปแบบการออกแบบวัสดุสำหรับคอลเล็กชันฟีเจอร์ที่ขับเคลื่อนด้วยแมชชีนเลิร์นนิง

เมื่อใช้โหมดสตรีมมิ่งในแอปพลิเคชันแบบเรียลไทม์ ให้ปฏิบัติตามคำแนะนำเหล่านี้เพื่อให้ได้เฟรมเรตที่ดีที่สุด:

  • อย่าใช้การตรวจจับวัตถุหลายรายการในโหมดสตรีมมิ่ง เนื่องจากอุปกรณ์ส่วนใหญ่ไม่สามารถสร้างเฟรมเรตที่เพียงพอได้

  • ปิดการใช้งานการจัดหมวดหมู่หากคุณไม่ต้องการมัน

  • คันเร่งเรียกไปที่เครื่องตรวจจับ หากมีเฟรมวิดีโอใหม่ในขณะที่ตัวตรวจจับกำลังทำงานอยู่ ให้ปล่อยเฟรมนั้น
  • หากคุณใช้เอาต์พุตของตัวตรวจจับเพื่อวางซ้อนกราฟิกบนรูปภาพอินพุต อันดับแรกรับผลลัพธ์จาก ML Kit จากนั้นเรนเดอร์รูปภาพและโอเวอร์เลย์ในขั้นตอนเดียว การทำเช่นนี้ คุณจะเรนเดอร์ไปยังพื้นผิวจอแสดงผลเพียงครั้งเดียวสำหรับแต่ละเฟรมอินพุต ดูตัวอย่างคลาส PreviewOverlayView และ FIRDetectionOverlayView ในแอปตัวอย่าง Showcase