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

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

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

ก่อนเริ่มต้น

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

    Swift

    import Firebase

    Objective-C

    @import Firebase;

1. กำหนดค่าตัวตรวจจับออบเจ็กต์

หากต้องการเริ่มตรวจจับและติดตามออบเจ็กต์ ให้สร้างอินสแตนซ์ของ VisionObjectDetector (ไม่บังคับ) ระบุการตั้งค่าตัวตรวจจับที่คุณต้องการ เปลี่ยนจากค่าเริ่มต้น

  1. กำหนดค่าตัวตรวจจับออบเจ็กต์สำหรับ Use Case ของคุณด้วย ออบเจ็กต์ VisionObjectDetectorOptions รายการ คุณสามารถเปลี่ยนสิ่งต่อไปนี้ได้ การตั้งค่าต่อไปนี้

    การตั้งค่าตัวตรวจจับวัตถุ
    โหมดการตรวจจับ .stream (ค่าเริ่มต้น) | วันที่ .singleImage

    ในโหมดสตรีม (ค่าเริ่มต้น) ตัวตรวจจับวัตถุจะทำงานโดยมีปริมาณต่ำมาก เวลาในการตอบสนอง แต่อาจทำให้ผลลัพธ์ไม่สมบูรณ์ (เช่น ไม่ได้ระบุ กรอบหรือหมวดหมู่) ในการเรียกใช้ 2-3 ครั้งแรก ตัวตรวจจับ นอกจากนี้ ตัวตรวจจับจะกำหนดการติดตามในโหมดสตรีม รหัสไปยังออบเจ็กต์ซึ่งใช้เพื่อติดตามวัตถุในเฟรมได้ ใช้โหมดนี้เมื่อคุณต้องการติดตามออบเจ็กต์ หรือเมื่อมีเวลาในการตอบสนองต่ำ มีความสำคัญ เช่น เมื่อประมวลผลสตรีมวิดีโอแบบเรียลไทม์

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

    ตรวจหาและติดตามวัตถุหลายรายการ false (ค่าเริ่มต้น) | วันที่ true

    สามารถตรวจจับและติดตามวัตถุได้สูงสุด 5 รายการ หรือเฉพาะวัตถุที่พบมากที่สุด ออบเจ็กต์ที่โดดเด่น (ค่าเริ่มต้น)

    จำแนกประเภทวัตถุ false (ค่าเริ่มต้น) | วันที่ true

    ระบุว่าจะจัดประเภทออบเจ็กต์ที่ตรวจพบเป็นหมวดหมู่คร่าวๆ หรือไม่ เมื่อเปิดใช้ ตัวตรวจจับวัตถุจะจัดประเภทออบเจ็กต์ลงใน หมวดหมู่ต่อไปนี้: สินค้าแฟชั่น อาหาร ของใช้ในบ้าน สถานที่ ต้นไม้ และสิ่งที่ไม่รู้จัก

    API การติดตามและตรวจจับออบเจ็กต์ได้รับการเพิ่มประสิทธิภาพสำหรับการใช้งานหลัก 2 รายการนี้ กรณี:

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

    วิธีกำหนดค่า API สำหรับกรณีการใช้งานเหล่านี้

    Swift

    // 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:

    Swift

    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

      Swift

      let image = VisionImage(image: uiImage)

      Objective-C

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

    วิธีใช้ CMSampleBufferRef

    1. สร้างออบเจ็กต์ VisionImageMetadata ที่ระบุ การวางแนวของข้อมูลภาพที่มีอยู่ใน บัฟเฟอร์ CMSampleBufferRef

      วิธีดูการวางแนวรูปภาพ

      Swift

      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;
        }
      }

      จากนั้นสร้างออบเจ็กต์ข้อมูลเมตา ดังนี้

      Swift

      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 และข้อมูลเมตาการหมุน:

      Swift

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

      Objective-C

      FIRVisionImage *image = [[FIRVisionImage alloc] initWithBuffer:sampleBuffer];
      image.metadata = metadata;
  2. ส่ง VisionImage ไปยังการประมวลผลรูปภาพของตัวตรวจจับวัตถุ คุณสามารถใช้เมธอด process(image:) แบบไม่พร้อมกันหรือ เมธอด results() แบบซิงโครนัส

    วิธีตรวจหาวัตถุแบบไม่พร้อมกัน

    Swift

    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.
                        // ...
                      }];
    

    วิธีตรวจหาวัตถุพร้อมกัน

    Swift

    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 จำนวนเต็มที่ระบุออบเจ็กต์ในรูปภาพ Nil ในซิงเกิล โหมดรูปภาพ
    classificationCategory หมวดหมู่คร่าวๆ ของออบเจ็กต์ หากตัวตรวจจับวัตถุไม่ เปิดใช้การแยกประเภทไว้ ซึ่งจะเป็น .unknown เสมอ
    confidence ค่าความเชื่อมั่นของการจัดประเภทออบเจ็กต์ หากออบเจ็กต์ ตัวตรวจจับไม่ได้เปิดใช้การแยกประเภท หรือออบเจ็กต์อยู่ จัดประเภทว่าไม่รู้จัก นี่คือ nil

    Swift

    // 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;
    }
    

การปรับปรุงความสามารถในการใช้งานและประสิทธิภาพ

โปรดปฏิบัติตามหลักเกณฑ์ต่อไปนี้ในแอปเพื่อให้ผู้ใช้ได้รับประสบการณ์ที่ดีที่สุด

  • การตรวจจับออบเจ็กต์ที่ประสบความสำเร็จขึ้นอยู่กับความซับซ้อนของภาพของออบเจ็กต์ วัตถุ ที่มีคุณลักษณะด้านภาพไม่กี่อย่าง อาจต้องใช้พื้นที่ส่วนใหญ่ของ รูปภาพที่จะตรวจจับ คุณควรให้คำแนะนำแก่ผู้ใช้เกี่ยวกับการจับภาพ ที่ทำงานกับวัตถุประเภทต่างๆ ที่คุณต้องการตรวจจับได้ดี
  • เมื่อใช้การจำแนกประเภท หากต้องการตรวจหาวัตถุที่ไม่ตก อยู่ในหมวดหมู่ที่สนับสนุนอย่างชัดเจน ใช้การจัดการพิเศษสำหรับสิ่งที่ไม่ทราบ ออบเจ็กต์

นอกจากนี้ คุณยังดู [แอปแสดงดีไซน์ Material ของ ML Kit][showcase-link]{: .external} และ ดีไซน์ Material คอลเล็กชันรูปแบบของฟีเจอร์ที่ขับเคลื่อนด้วยแมชชีนเลิร์นนิง

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

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

  • ปิดใช้การแยกประเภทหากไม่ต้องการใช้

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