ตรวจหา ติดตาม และจัดประเภทออบเจ็กต์ด้วยโมเดลการแยกประเภทที่กำหนดเองใน iOS

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

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

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

การผสานรวมโมเดลที่กำหนดเองทำได้ 2 วิธี คุณสามารถรวมโมเดลไว้ด้วยกันโดยวางไว้ในโฟลเดอร์ชิ้นงานของแอป หรือดาวน์โหลดแบบไดนามิกจาก Cloud Storage ตารางต่อไปนี้เปรียบเทียบตัวเลือกทั้ง 2 รายการ

โมเดลที่รวมไว้ด้วยกัน โมเดลที่โฮสต์
โมเดลเป็นส่วนหนึ่งของไฟล์ .ipa ของแอป ซึ่ง เพิ่มขนาดของไฟล์ โมเดลไม่ได้เป็นส่วนหนึ่งของไฟล์ .ipa ของแอป โดยจะโฮสต์ด้วยการอัปโหลดไปยัง Cloud Storage เราขอแนะนำให้ใช้ Cloud Storage สำหรับ Firebase
โมเดลพร้อมใช้งานทันที แม้ว่าอุปกรณ์ Android จะออฟไลน์อยู่ก็ตาม แอปของคุณต้องมีโค้ดเพื่อดาวน์โหลดโมเดลตามความต้องการ
ไม่จำเป็นต้องมีโปรเจ็กต์ Firebase ต้องมีโปรเจ็กต์ Firebase (หากใช้ Cloud Storage สำหรับ Firebase)
คุณต้องเผยแพร่แอปอีกครั้งเพื่ออัปเดตโมเดล ส่งการอัปเดตโมเดลโดยไม่ต้องเผยแพร่แอปอีกครั้ง
ไม่มีการทดสอบ A/B ในตัว การทดสอบ A/B ด้วย การกำหนดค่าระยะไกลของ Firebase

ลองเลย

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

  1. ใส่ไลบรารี ML Kit ใน Podfile ดังนี้

    pod 'GoogleMLKit/ObjectDetectionCustom', '8.0.0'
    
  2. หลังจากติดตั้งหรืออัปเดต Pods ของโปรเจ็กต์แล้ว ให้เปิดโปรเจ็กต์ Xcode โดยใช้ไฟล์ .xcworkspace ML Kit รองรับใน Xcode เวอร์ชัน 13.2.1 ขึ้นไป

  3. หากต้องการดาวน์โหลดโมเดลโดยใช้ Cloud Storage สำหรับ Firebase ให้ ตรวจสอบว่าคุณ ได้เพิ่ม Firebase ลงในโปรเจ็กต์ iOS แล้ว หากยังไม่ได้ดำเนินการ การดำเนินการนี้ไม่จำเป็นเมื่อคุณรวม โมเดลไว้ด้วยกัน

1. โหลดโมเดล

กำหนดค่าแหล่งที่มาของโมเดลในเครื่อง

วิธีรวมโมเดลไว้กับแอป

  1. คัดลอกไฟล์โมเดล (โดยปกติจะลงท้ายด้วย .tflite หรือ .lite) ไปยังโปรเจ็กต์ Xcode โดยตรวจสอบว่าได้เลือก Copy bundle resources เมื่อดำเนินการ ไฟล์โมเดลจะรวมอยู่ใน App Bundle และพร้อมใช้งานสำหรับ ML Kit

  2. สร้างออบเจ็กต์ LocalModel โดยระบุเส้นทางไปยังไฟล์โมเดล

    Swift

    let localModel = LocalModel(path: localModelFilePath)

    Objective-C

    MLKLocalModel *localModel =
        [[MLKLocalModel alloc] initWithPath:localModelFilePath];

กำหนดค่าแหล่งที่มาของโมเดลที่โฮสต์จากระยะไกล

หากต้องการใช้โมเดลที่โฮสต์จากระยะไกล คุณต้องดาวน์โหลดไฟล์โมเดลลงในพื้นที่เก็บข้อมูลในเครื่องของอุปกรณ์โดยใช้ตรรกะของแอปเอง แล้วโหลดเป็นโมเดลในเครื่อง เราขอแนะนำให้ใช้ Cloud Storage for Firebase เพื่อโฮสต์โมเดล ดูรายละเอียดการใช้งานได้ที่ คู่มือการย้ายข้อมูลจาก Firebase ML ไปยัง Cloud Storage

2. กำหนดค่าตัวตรวจจับวัตถุ

หลังจากกำหนดค่าแหล่งที่มาของโมเดลแล้ว ให้กำหนดค่าตัวตรวจจับวัตถุสำหรับกรณีการใช้งานของคุณด้วยออบเจ็กต์ CustomObjectDetectorOptions คุณสามารถเปลี่ยนการตั้งค่าต่อไปนี้ได้

การตั้งค่าตัวตรวจจับวัตถุ
โหมดการตรวจจับ STREAM_MODE (ค่าเริ่มต้น) | SINGLE_IMAGE_MODE

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

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

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

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

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

เลือกว่าจะจัดประเภทวัตถุที่ตรวจพบโดยใช้โมเดลตัวแยกประเภทแบบกำหนดเองที่ให้ไว้หรือไม่ หากต้องการใช้โมเดลการจัดประเภทที่กำหนดเอง คุณต้องตั้งค่านี้เป็น true

เกณฑ์ความเชื่อมั่นในการจัดประเภท

คะแนนความเชื่อมั่นขั้นต่ำของป้ายกำกับที่ตรวจพบ หากไม่ได้ตั้งค่า ระบบจะใช้เกณฑ์ตัวแยกประเภทที่ระบุโดยข้อมูลเมตาของโมเดล หากโมเดลไม่มีข้อมูลเมตาหรือข้อมูลเมตาไม่ได้ ระบุเกณฑ์ตัวแยกประเภท ระบบจะใช้เกณฑ์เริ่มต้นที่ 0.0

ป้ายกำกับสูงสุดต่อวัตถุ

จำนวนป้ายกำกับสูงสุดต่อวัตถุที่ตัวตรวจจับจะ แสดงผล หากไม่ได้ตั้งค่า ระบบจะใช้ค่าเริ่มต้นที่ 10

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

Swift

let options = CustomObjectDetectorOptions(localModel: localModel)
options.detectorMode = .singleImage
options.shouldEnableClassification = true
options.shouldEnableMultipleObjects = true
options.classificationConfidenceThreshold = NSNumber(value: 0.5)
options.maxPerObjectLabelCount = 3

Objective-C

MLKCustomObjectDetectorOptions *options =
    [[MLKCustomObjectDetectorOptions alloc] initWithLocalModel:localModel];
options.detectorMode = MLKObjectDetectorModeSingleImage;
options.shouldEnableClassification = YES;
options.shouldEnableMultipleObjects = YES;
options.classificationConfidenceThreshold = @(0.5);
options.maxPerObjectLabelCount = 3;

หากมีโมเดลที่โฮสต์จากระยะไกล คุณจะต้องตรวจสอบว่าได้ดาวน์โหลดโมเดลแล้วก่อนที่จะดำเนินการ

แม้ว่าคุณจะต้องยืนยันการดาวน์โหลดโมเดลก่อนที่จะเรียกใช้ตัวตรวจจับวัตถุเท่านั้น แต่หากคุณมีทั้งโมเดลที่โฮสต์จากระยะไกลและโมเดลที่รวมไว้ด้วยกันในเครื่อง การตรวจสอบนี้เมื่อสร้างอินสแตนซ์ ObjectDetector อาจเป็นเรื่องสมเหตุสมผล กล่าวคือ สร้างตัวตรวจจับจากโมเดลระยะไกลหากดาวน์โหลดแล้ว และสร้างจากโมเดลในเครื่องหากยังไม่ได้ดาวน์โหลด

Swift

// Path where your download logic saves the model
let documentDirectory = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first!
let localModelURL = documentDirectory.appendingPathComponent("my_remote_model.tflite")

let model: LocalModel
if FileManager.default.fileExists(atPath: localModelURL.path) {
  // Use the downloaded model
  model = LocalModel(path: localModelURL.path)
} else {
  // Fall back to bundled model
  guard let bundledModelPath = Bundle.main.path(forResource: "model", ofType: "tflite") else { return }
  model = LocalModel(path: bundledModelPath)
}

let options = CustomObjectDetectorOptions(localModel: model)
options.detectorMode = .singleImage
options.shouldEnableClassification = true
options.shouldEnableMultipleObjects = true
options.classificationConfidenceThreshold = NSNumber(value: 0.5)
options.maxPerObjectLabelCount = 3
let objectDetector = ObjectDetector.objectDetector(options: options)

Objective-C

NSString *documentsDirectory = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) firstObject];
NSString *localModelPath = [documentsDirectory stringByAppendingPathComponent:@"my_remote_model.tflite"];

MLKLocalModel *model;
if ([NSFileManager.defaultManager fileExistsAtPath:localModelPath]) {
  // Use the downloaded model
  model = [[MLKLocalModel alloc] initWithPath:localModelPath];
} else {
  // Fall back to bundled model
  NSString *bundledModelPath = [NSBundle.mainBundle pathForResource:@"model" ofType:@"tflite"];
  model = [[MLKLocalModel alloc] initWithPath:bundledModelPath];
}

MLKCustomObjectDetectorOptions *options = [[MLKCustomObjectDetectorOptions alloc] initWithLocalModel:model];
options.detectorMode = MLKObjectDetectorModeSingleImage;
options.shouldEnableClassification = YES;
options.shouldEnableMultipleObjects = YES;
options.classificationConfidenceThreshold = @(0.5);
options.maxPerObjectLabelCount = 3;
MLKObjectDetector *objectDetector = [MLKObjectDetector objectDetectorWithOptions:options];

หากมีเฉพาะโมเดลที่โฮสต์จากระยะไกล คุณควรปิดใช้ฟังก์ชันการทำงานที่เกี่ยวข้องกับโมเดล เช่น ทำให้ส่วนหนึ่งของ UI เป็นสีเทาหรือซ่อนไว้ จนกว่าจะยืนยันว่าได้ดาวน์โหลดโมเดลแล้ว

Swift

let documentDirectory = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first!
let localModelURL = documentDirectory.appendingPathComponent("my_remote_model.tflite")
if FileManager.default.fileExists(atPath: localModelURL.path) {
  // Model is already cached, initialize immediately
  self.initializeDetector(with: localModelURL)
} else {
  // Model is not yet available, show loading UI and start download
  self.showLoadingUI()
  let storage = Storage.storage()
  let modelRef = storage.reference(forURL: "gs://YOUR_BUCKET/path/to/model.tflite")
  modelRef.write(toFile: localModelURL) { url, error in
    self.hideLoadingUI()
    if let error = error {
      // Handle download error
      self.showErrorUI()
    } else if let modelURL = url {
      // Download success, initialize detector
      self.initializeDetector(with: modelURL)
    }
  }
}

func initializeDetector(with modelURL: URL) {
  let localModel = LocalModel(path: modelURL.path)
  let options = CustomObjectDetectorOptions(localModel: localModel)
  options.detectorMode = .singleImage
  options.shouldEnableClassification = true
  options.shouldEnableMultipleObjects = true
  self.objectDetector = ObjectDetector.objectDetector(options: options)
  // Enable ML features in UI
  self.enableMLFeatures()
}

Objective-C

NSString *documentsDirectory = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) firstObject];
NSString *localModelPath = [documentsDirectory stringByAppendingPathComponent:@"my_remote_model.tflite"];
NSURL *localModelURL = [NSURL fileURLWithPath:localModelPath];

if ([NSFileManager.defaultManager fileExistsAtPath:localModelPath]) {
  // Model is already cached, initialize immediately
  [self initializeDetectorWithURL:localModelURL];
} else {
  // Model is not yet available, show loading UI and start download
  [self showLoadingUI];

  FIRStorage *storage = [FIRStorage storage];
  FIRStorageReference *modelRef = [storage referenceForURL:@"gs://YOUR_BUCKET/path/to/model.tflite"];

  [modelRef writeToFile:localModelURL
             completion:^(NSURL * _Nullable URL, NSError * _Nullable error) {
               [self hideLoadingUI];
               if (error != nil) {
                 // Handle download error
                 [self showErrorUI];
               } else {
                 // Download success, initialize detector
                 [self initializeDetectorWithURL:URL];
               }
             }];
}

- (void)initializeDetectorWithURL:(NSURL *)modelURL {
  MLKLocalModel *localModel = [[MLKLocalModel alloc] initWithPath:modelURL.path];
  MLKCustomObjectDetectorOptions *options = [[MLKCustomObjectDetectorOptions alloc] initWithLocalModel:localModel];
  options.detectorMode = MLKObjectDetectorModeSingleImage;
  options.shouldEnableClassification = YES;
  options.shouldEnableMultipleObjects = YES;
  self.objectDetector = [MLKObjectDetector objectDetectorWithOptions:options];

  // Enable ML features in UI
  [self enableMLFeatures];
}

API การตรวจจับและติดตามวัตถุได้รับการปรับให้เหมาะกับกรณีการใช้งานหลัก 2 กรณีต่อไปนี้

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

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

Swift

// Live detection and tracking
let options = CustomObjectDetectorOptions(localModel: localModel)
options.shouldEnableClassification = true
options.maxPerObjectLabelCount = 3

// Multiple object detection in static images
let options = CustomObjectDetectorOptions(localModel: localModel)
options.detectorMode = .singleImage
options.shouldEnableMultipleObjects = true
options.shouldEnableClassification = true
options.maxPerObjectLabelCount = 3

Objective-C

// Live detection and tracking
MLKCustomObjectDetectorOptions *options =
    [[MLKCustomObjectDetectorOptions alloc] initWithLocalModel:localModel];
options.shouldEnableClassification = YES;
options.maxPerObjectLabelCount = 3;

// Multiple object detection in static images
MLKCustomObjectDetectorOptions *options =
    [[MLKCustomObjectDetectorOptions alloc] initWithLocalModel:localModel];
options.detectorMode = MLKObjectDetectorModeSingleImage;
options.shouldEnableMultipleObjects = YES;
options.shouldEnableClassification = YES;
options.maxPerObjectLabelCount = 3;

3. เตรียมรูปภาพอินพุต

สร้างออบเจ็กต์ VisionImage โดยใช้ UIImage หรือ CMSampleBuffer

หากใช้ UIImage ให้ทำตามขั้นตอนต่อไปนี้

  • สร้างออบเจ็กต์ VisionImage ด้วย UIImage และตรวจสอบว่าได้ระบุ .orientation ที่ถูกต้อง

    Swift

    let image = VisionImage(image: UIImage)
    visionImage.orientation = image.imageOrientation

    Objective-C

    MLKVisionImage *visionImage = [[MLKVisionImage alloc] initWithImage:image];
    visionImage.orientation = image.imageOrientation;

หากใช้ CMSampleBuffer ให้ทำตามขั้นตอนต่อไปนี้

  • ระบุการวางแนวของข้อมูลรูปภาพที่อยู่ใน CMSampleBuffer

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

    Swift

    func imageOrientation(
      deviceOrientation: UIDeviceOrientation,
      cameraPosition: AVCaptureDevice.Position
    ) -> UIImage.Orientation {
      switch deviceOrientation {
      case .portrait:
        return cameraPosition == .front ? .leftMirrored : .right
      case .landscapeLeft:
        return cameraPosition == .front ? .downMirrored : .up
      case .portraitUpsideDown:
        return cameraPosition == .front ? .rightMirrored : .left
      case .landscapeRight:
        return cameraPosition == .front ? .upMirrored : .down
      case .faceDown, .faceUp, .unknown:
        return .up
      }
    }
          

    Objective-C

    - (UIImageOrientation)
      imageOrientationFromDeviceOrientation:(UIDeviceOrientation)deviceOrientation
                             cameraPosition:(AVCaptureDevicePosition)cameraPosition {
      switch (deviceOrientation) {
        case UIDeviceOrientationPortrait:
          return cameraPosition == AVCaptureDevicePositionFront ? UIImageOrientationLeftMirrored
                                                                : UIImageOrientationRight;
    
        case UIDeviceOrientationLandscapeLeft:
          return cameraPosition == AVCaptureDevicePositionFront ? UIImageOrientationDownMirrored
                                                                : UIImageOrientationUp;
        case UIDeviceOrientationPortraitUpsideDown:
          return cameraPosition == AVCaptureDevicePositionFront ? UIImageOrientationRightMirrored
                                                                : UIImageOrientationLeft;
        case UIDeviceOrientationLandscapeRight:
          return cameraPosition == AVCaptureDevicePositionFront ? UIImageOrientationUpMirrored
                                                                : UIImageOrientationDown;
        case UIDeviceOrientationUnknown:
        case UIDeviceOrientationFaceUp:
        case UIDeviceOrientationFaceDown:
          return UIImageOrientationUp;
      }
    }
          
  • สร้างออบเจ็กต์ VisionImage โดยใช้ CMSampleBuffer ออบเจ็กต์และการวางแนว

    Swift

    let image = VisionImage(buffer: sampleBuffer)
    image.orientation = imageOrientation(
      deviceOrientation: UIDevice.current.orientation,
      cameraPosition: cameraPosition)

    Objective-C

     MLKVisionImage *image = [[MLKVisionImage alloc] initWithBuffer:sampleBuffer];
     image.orientation =
       [self imageOrientationFromDeviceOrientation:UIDevice.currentDevice.orientation
                                    cameraPosition:cameraPosition];

4. สร้างและเรียกใช้ตัวตรวจจับวัตถุ

  1. สร้างตัวตรวจจับวัตถุใหม่

    Swift

    let objectDetector = ObjectDetector.objectDetector(options: options)

    Objective-C

    MLKObjectDetector *objectDetector = [MLKObjectDetector objectDetectorWithOptions:options];
  2. จากนั้นใช้ตัวตรวจจับดังนี้

    แบบไม่พร้อมกัน

    Swift

    objectDetector.process(image) { objects, error in
        guard error == nil, let objects = objects, !objects.isEmpty else {
            // Handle the error.
            return
        }
        // Show results.
    }

    Objective-C

    [objectDetector
        processImage:image
          completion:^(NSArray *_Nullable objects,
                       NSError *_Nullable error) {
            if (objects.count == 0) {
                // Handle the error.
                return;
            }
            // Show results.
         }];

    แบบพร้อมกัน

    Swift

    var objects: [Object]
    do {
        objects = try objectDetector.results(in: image)
    } catch let error {
        // Handle the error.
        return
    }
    // Show results.

    Objective-C

    NSError *error;
    NSArray *objects =
        [objectDetector resultsInImage:image error:&error];
    // Show results or handle the error.

5. ดูข้อมูลเกี่ยวกับวัตถุที่ติดป้ายกำกับ

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

Object แต่ละรายการมีพร็อพเพอร์ตี้ต่อไปนี้

frame A CGRect ที่ระบุตำแหน่งของวัตถุใน รูปภาพ
trackingID จำนวนเต็มที่ระบุวัตถุในรูปภาพ หรือ `nil` ใน SINGLE_IMAGE_MODE
labels
label.text คำอธิบายข้อความของป้ายกำกับ จะแสดงผลก็ต่อเมื่อข้อมูลเมตาของโมเดล LiteRT มีคำอธิบายป้ายกำกับ
label.index ดัชนีของป้ายกำกับในป้ายกำกับทั้งหมดที่ตัวแยกประเภท รองรับ
label.confidence ค่า Confidence ของการจัดประเภทวัตถุ

Swift

// objects contains one item if multiple object detection wasn't enabled.
for object in objects {
  let frame = object.frame
  let trackingID = object.trackingID
  let description = object.labels.enumerated().map { (index, label) in
    "Label \(index): \(label.text), \(label.confidence), \(label.index)"
  }.joined(separator: "\n")
}

Objective-C

// The list of detected objects contains one item if multiple object detection
// wasn't enabled.
for (MLKObject *object in objects) {
  CGRect frame = object.frame;
  NSNumber *trackingID = object.trackingID;
  for (MLKObjectLabel *label in object.labels) {
    NSString *labelString =
        [NSString stringWithFormat:@"%@, %f, %lu",
                                   label.text,
                                   label.confidence,
                                   (unsigned long)label.index];
  }
}

การรับประกันประสบการณ์การใช้งานที่ยอดเยี่ยม

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

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

นอกจากนี้ โปรดดู แอปตัวอย่าง ML Kit Material Design และ คอลเล็กชัน รูปแบบ Material Design สำหรับฟีเจอร์ที่ขับเคลื่อนโดยแมชชีนเลิร์นนิง

การปรับปรุงประสิทธิภาพการทำงาน

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

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

  • สำหรับการประมวลผลเฟรมวิดีโอ ให้ใช้ API แบบพร้อมกัน results(in:) ของตัวตรวจจับ เรียกใช้เมธอดนี้จากฟังก์ชัน AVCaptureVideoDataOutputSampleBufferDelegate ของ captureOutput(_, didOutput:from:) เพื่อรับผลลัพธ์จากเฟรมวิดีโอที่ระบุแบบพร้อมกัน ตั้งค่า AVCaptureVideoDataOutput ของ alwaysDiscardsLateVideoFrames เป็น true เพื่อควบคุมการเรียกใช้ตัวตรวจจับ หากเฟรมวิดีโอใหม่ พร้อมใช้งานขณะที่ตัวตรวจจับกำลังทำงาน ระบบจะทิ้งเฟรมนั้น
  • หากใช้เอาต์พุตของตัวตรวจจับเพื่อซ้อนทับกราฟิกบน รูปภาพอินพุต ให้รับผลลัพธ์จาก ML Kit ก่อน แล้วจึงแสดงรูปภาพ และซ้อนทับในขั้นตอนเดียว การทำเช่นนี้จะทำให้คุณแสดงผลไปยังพื้นผิวการแสดงผล เพียงครั้งเดียวสำหรับเฟรมอินพุตที่ประมวลผลแต่ละเฟรม ดูตัวอย่างได้ที่ updatePreviewOverlayViewWithLastFrame ในตัวอย่างเริ่มต้นใช้งานด่วนของ ML Kit