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

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

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

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

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

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

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

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

    สําหรับการรวมกลุ่มรูปแบบกับแอป

    pod 'GoogleMLKit/ObjectDetectionCustom', '3.2.0'
    

    หากต้องการดาวน์โหลดโมเดลแบบไดนามิกจาก Firebase ให้เพิ่มทรัพยากร Dependency LinkFirebase:

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

  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 } และคอลเล็กชัน ดีไซน์ Material สําหรับฟีเจอร์ที่ขับเคลื่อนโดยแมชชีนเลิร์นนิง

Improving performance

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

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

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