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

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

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

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

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

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

ลองใช้งาน

ข้อควรทราบก่อนที่จะเริ่มต้น

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

    สําหรับกลุ่มแพ็กเกจกับแอปของคุณ ให้ทําดังนี้

    pod 'GoogleMLKit/ObjectDetectionCustom', '3.2.0'
    

    สําหรับการดาวน์โหลดโมเดลแบบไดนามิกจาก Firebase ให้เพิ่มการอ้างอิง LinkFirebase

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

  3. หากต้องการดาวน์โหลดโมเดล โปรดตรวจสอบว่าได้เพิ่ม 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];

กําหนดค่าแหล่งที่มาของโมเดลที่โฮสต์ใน Firebase

หากต้องการใช้โมเดลที่โฮสต์จากระยะไกล ให้สร้างออบเจ็กต์ CustomRemoteModel โดยระบุชื่อที่คุณกําหนดโมเดลเมื่อเผยแพร่

Swift

let firebaseModelSource = FirebaseModelSource(
    name: "your_remote_model") // The name you assigned in
                               // the Firebase console.
let remoteModel = CustomRemoteModel(remoteModelSource: firebaseModelSource)

Objective-C

MLKFirebaseModelSource *firebaseModelSource =
    [[MLKFirebaseModelSource alloc]
        initWithName:@"your_remote_model"]; // The name you assigned in
                                            // the Firebase console.
MLKCustomRemoteModel *remoteModel =
    [[MLKCustomRemoteModel alloc]
        initWithRemoteModelSource:firebaseModelSource];

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

Swift

let downloadConditions = ModelDownloadConditions(
  allowsCellularAccess: true,
  allowsBackgroundDownloading: true
)

let downloadProgress = ModelManager.modelManager().download(
  remoteModel,
  conditions: downloadConditions
)

Objective-C

MLKModelDownloadConditions *downloadConditions =
    [[MLKModelDownloadConditions alloc] initWithAllowsCellularAccess:YES
                                         allowsBackgroundDownloading:YES];

NSProgress *downloadProgress =
    [[MLKModelManager modelManager] downloadModel:remoteModel
                                       conditions:downloadConditions];

แอปจํานวนมากเริ่มงานดาวน์โหลดในโค้ดเริ่มต้น แต่คุณสามารถทําได้ทุกเมื่อก่อนที่จะต้องใช้โมเดล

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;

หากมีโมเดลที่โฮสต์จากระยะไกล คุณจะต้องตรวจสอบว่าโมเดลนั้นดาวน์โหลดแล้วก่อนที่จะเรียกใช้ คุณตรวจสอบสถานะของงานดาวน์โหลดโมเดลได้โดยใช้เมธอด isModelDownloaded(remoteModel:) ของผู้จัดการโมเดล

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

Swift

var options: CustomObjectDetectorOptions!
if (ModelManager.modelManager().isModelDownloaded(remoteModel)) {
  options = CustomObjectDetectorOptions(remoteModel: remoteModel)
} else {
  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;
if ([[MLKModelManager modelManager] isModelDownloaded:remoteModel]) {
  options = [[MLKCustomObjectDetectorOptions alloc] initWithRemoteModel:remoteModel];
} else {
  options = [[MLKCustomObjectDetectorOptions alloc] initWithLocalModel:localModel];
}
options.detectorMode = MLKObjectDetectorModeSingleImage;
options.shouldEnableClassification = YES;
options.shouldEnableMultipleObjects = YES;
options.classificationConfidenceThreshold = @(0.5);
options.maxPerObjectLabelCount = 3;

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

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

Swift

NotificationCenter.default.addObserver(
    forName: .mlkitModelDownloadDidSucceed,
    object: nil,
    queue: nil
) { [weak self] notification in
    guard let strongSelf = self,
        let userInfo = notification.userInfo,
        let model = userInfo[ModelDownloadUserInfoKey.remoteModel.rawValue]
            as? RemoteModel,
        model.name == "your_remote_model"
        else { return }
    // The model was downloaded and is available on the device
}

NotificationCenter.default.addObserver(
    forName: .mlkitModelDownloadDidFail,
    object: nil,
    queue: nil
) { [weak self] notification in
    guard let strongSelf = self,
        let userInfo = notification.userInfo,
        let model = userInfo[ModelDownloadUserInfoKey.remoteModel.rawValue]
            as? RemoteModel
        else { return }
    let error = userInfo[ModelDownloadUserInfoKey.error.rawValue]
    // ...
}

Objective-C

__weak typeof(self) weakSelf = self;

[NSNotificationCenter.defaultCenter
    addObserverForName:MLKModelDownloadDidSucceedNotification
                object:nil
                 queue:nil
            usingBlock:^(NSNotification *_Nonnull note) {
              if (weakSelf == nil | note.userInfo == nil) {
                return;
              }
              __strong typeof(self) strongSelf = weakSelf;

              MLKRemoteModel *model = note.userInfo[MLKModelDownloadUserInfoKeyRemoteModel];
              if ([model.name isEqualToString:@"your_remote_model"]) {
                // The model was downloaded and is available on the device
              }
            }];

[NSNotificationCenter.defaultCenter
    addObserverForName:MLKModelDownloadDidFailNotification
                object:nil
                 queue:nil
            usingBlock:^(NSNotification *_Nonnull note) {
              if (weakSelf == nil | note.userInfo == nil) {
                return;
              }
              __strong typeof(self) strongSelf = weakSelf;

              NSError *error = note.userInfo[MLKModelDownloadUserInfoKeyError];
            }];

การตรวจจับออบเจ็กต์และ 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 ไปยังเครื่องจัดการที่สําเร็จหรือแสดงผลรายการ โดยขึ้นอยู่กับว่าคุณเรียกใช้เมธอดแบบไม่พร้อมกันหรือซิงโครนัส

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

frame CGRect แสดงตําแหน่งของออบเจ็กต์ในรูปภาพ
trackingID จํานวนเต็มที่ระบุออบเจ็กต์ในรูปภาพ หรือ "nil" ใน SINGLE_IMAGE_MODE
labels
label.text คําอธิบายข้อความของป้ายกํากับ แสดงเฉพาะในกรณีที่ข้อมูลเมตาของโมเดล TensorFlow Lite มีคําอธิบายป้ายกํากับ
label.index ดัชนีของป้ายกํากับจากป้ายกํากับทั้งหมดที่ตัวแยกประเภทรองรับ
label.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 Showcase]"[showcase-link]{: .external } และคอลเล็กชันรูปแบบสําหรับฟีเจอร์ที่ขับเคลื่อนโดยแมชชีนเลิร์นนิง

Improving performance

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

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

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