คุณสามารถใช้ ML Kit เพื่อจดจำเอนทิตีในรูปภาพและติดป้ายกำกับรายการดังกล่าว API นี้รองรับโมเดลการจัดประเภทรูปภาพที่กำหนดเองหลากหลายรูปแบบ โปรด โปรดดูที่โมเดลที่กำหนดเองด้วย ML Kit เพื่อดูคำแนะนำเกี่ยวกับ ข้อกำหนดความเข้ากันได้กับโมเดล วิธีค้นหาโมเดลก่อนการฝึก และวิธีฝึกโมเดลของคุณเอง
มี 2 วิธีในการรวมโมเดลที่กำหนดเอง คุณสามารถรวมกลุ่มโมเดลได้โดย ใส่ลงในโฟลเดอร์เนื้อหาของแอป หรือคุณจะดาวน์โหลดแบบไดนามิกก็ได้ จาก Firebase ตารางต่อไปนี้จะเปรียบเทียบทั้ง 2 ตัวเลือก
| โมเดลแบบกลุ่ม | โมเดลที่โฮสต์ |
|---|---|
| โมเดลนี้เป็นส่วนหนึ่งของ APK ของแอป ซึ่งจะเพิ่มขนาด | โมเดลนี้ไม่ได้เป็นส่วนหนึ่งของ APK ของคุณ ซึ่งโฮสต์โดยการอัปโหลดไปยัง แมชชีนเลิร์นนิงของ Firebase |
| โมเดลดังกล่าวจะพร้อมใช้งานทันที แม้ว่าอุปกรณ์ Android จะออฟไลน์อยู่ | โมเดลจะดาวน์โหลดแบบออนดีมานด์ |
| ไม่จำเป็นต้องมีโปรเจ็กต์ Firebase | ต้องมีโปรเจ็กต์ Firebase |
| คุณต้องเผยแพร่แอปอีกครั้งเพื่ออัปเดตโมเดล | พุชการอัปเดตโมเดลโดยไม่เผยแพร่แอปซ้ำ |
| ไม่มีการทดสอบ A/B ในตัว | การทดสอบ A/B ที่ง่ายดายด้วยการกำหนดค่าระยะไกลของ Firebase |
ลองเลย
- ดูแอป Vision Quickstart สำหรับตัวอย่างการใช้งานโมเดล Bundle และ แอปการเริ่มต้นอย่างรวดเร็วของ automl สำหรับ ตัวอย่างการใช้โมเดลที่โฮสต์
ก่อนเริ่มต้น
รวมไลบรารี ML Kit ไว้ใน Podfile ดังนี้
สำหรับการรวมโมเดลกับแอป ให้ทำดังนี้
pod 'GoogleMLKit/ImageLabelingCustom', '8.0.0'สำหรับการดาวน์โหลดโมเดลแบบไดนามิกจาก Firebase ให้เพิ่ม
LinkFirebaseการพึ่งพา:pod 'GoogleMLKit/ImageLabelingCustom', '8.0.0' pod 'GoogleMLKit/LinkFirebase', '8.0.0'หลังจากติดตั้งหรืออัปเดตพ็อดของโปรเจ็กต์แล้ว ให้เปิดโปรเจ็กต์ Xcode โดยใช้
.xcworkspaceรองรับ ML Kit ใน Xcode เวอร์ชัน 13.2.1 หรือสูงกว่าหากต้องการดาวน์โหลดโมเดล โปรดตรวจสอบว่า เพิ่ม Firebase ลงในโปรเจ็กต์ iOS หากคุณยังไม่ได้ดำเนินการ ไม่จำเป็นต้องทำขั้นตอนนี้เมื่อคุณรวมชุด โมเดล
1. โหลดโมเดล
กำหนดค่าต้นทางของโมเดลในเครื่อง
วิธีการรวมโมเดลกับแอปมีดังนี้
คัดลอกไฟล์โมเดล (โดยปกติจะลงท้ายด้วย
.tfliteหรือ.lite) ไปยัง Xcode ให้เลือกCopy bundle resourcesเมื่อคุณดำเนินการดังกล่าว ไฟล์โมเดลจะรวมอยู่ใน App Bundle และพร้อมใช้งานสำหรับ ML Kitสร้างออบเจ็กต์
LocalModelโดยระบุเส้นทางไปยังไฟล์โมเดลSwift
let localModel = LocalModel(path: localModelFilePath)
Objective-C
MLKLocalModel *localModel = [[MLKLocalModel alloc] initWithPath:localModelFilePath];
กำหนดค่าแหล่งที่มาของโมเดลที่โฮสต์กับ Firebase
หากต้องการใช้โมเดลที่โฮสต์จากระยะไกล ให้สร้างออบเจ็กต์ RemoteModel โดยระบุ
ชื่อที่คุณกำหนดโมเดลเมื่อเผยแพร่:
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];
แอปจำนวนมากเริ่มงานดาวน์โหลดในโค้ดเริ่มต้น แต่คุณ จากนั้นคุณจะสามารถทำได้ทุกเมื่อก่อนที่จะต้องใช้โมเดลนี้
กำหนดค่าเครื่องมือติดป้ายกำกับรูปภาพ
หลังจากกำหนดค่าแหล่งที่มาของโมเดลแล้ว ให้สร้างออบเจ็กต์ ImageLabeler จาก 1 รายการ
ทั้งหมด
โดยมีตัวเลือกดังต่อไปนี้
| ตัวเลือก | |
|---|---|
confidenceThreshold
|
คะแนนความเชื่อมั่นขั้นต่ำของป้ายกำกับที่ตรวจพบ หากไม่ได้ตั้งค่าไว้ รายการใดรายการหนึ่ง จะมีการใช้เกณฑ์ตัวแยกประเภทที่ระบุโดยข้อมูลเมตาของโมเดล ถ้าโมเดลไม่มีข้อมูลเมตาหรือข้อมูลเมตาไม่มี ระบุเกณฑ์ของตัวแยกประเภท โดยเกณฑ์เริ่มต้นที่มีค่าเท่ากับ 0.0 |
maxResultCount
|
จำนวนป้ายกำกับสูงสุดที่จะแสดงผล หากไม่ได้ตั้งค่า ระบบจะใช้ค่าเริ่มต้น ระบบจะใช้ 10 |
หากคุณมีเฉพาะโมเดลที่รวมภายในเครื่อง ให้สร้างผู้ติดป้ายกำกับจาก
ออบเจ็กต์ LocalModel รายการ:
Swift
let options = CustomImageLabelerOptions(localModel: localModel) options.confidenceThreshold = NSNumber(value: 0.0) let imageLabeler = ImageLabeler.imageLabeler(options: options)
Objective-C
MLKCustomImageLabelerOptions *options = [[MLKCustomImageLabelerOptions alloc] initWithLocalModel:localModel]; options.confidenceThreshold = @(0.0); MLKImageLabeler *imageLabeler = [MLKImageLabeler imageLabelerWithOptions:options];
หากคุณมีโมเดลที่โฮสต์จากระยะไกล คุณจะต้องตรวจสอบว่ามีการ
ซึ่งดาวน์โหลดมาก่อนที่จะเรียกใช้ คุณตรวจสอบสถานะการดาวน์โหลดโมเดลได้
โดยใช้เมธอด isModelDownloaded(remoteModel:) ของผู้จัดการโมเดล
แม้ว่าคุณจะต้องยืนยันเรื่องนี้ก่อนเรียกใช้ผู้ติดป้ายกำกับเท่านั้นหากคุณ
มีทั้งโมเดลที่โฮสต์จากระยะไกลและโมเดลที่รวมอยู่ภายใน
เหมาะสมที่จะดำเนินการตรวจสอบนี้เมื่อเริ่มต้น ImageLabeler: สร้าง
ผู้ติดป้ายกำกับจากโมเดลระยะไกลหากดาวน์โหลดแล้ว และจากโมเดลในเครื่อง
หรือไม่เช่นนั้น
Swift
var options: CustomImageLabelerOptions! if (ModelManager.modelManager().isModelDownloaded(remoteModel)) { options = CustomImageLabelerOptions(remoteModel: remoteModel) } else { options = CustomImageLabelerOptions(localModel: localModel) } options.confidenceThreshold = NSNumber(value: 0.0) let imageLabeler = ImageLabeler.imageLabeler(options: options)
Objective-C
MLKCustomImageLabelerOptions *options; if ([[MLKModelManager modelManager] isModelDownloaded:remoteModel]) { options = [[MLKCustomImageLabelerOptions alloc] initWithRemoteModel:remoteModel]; } else { options = [[MLKCustomImageLabelerOptions alloc] initWithLocalModel:localModel]; } options.confidenceThreshold = @(0.0); MLKImageLabeler *imageLabeler = [MLKImageLabeler imageLabelerWithOptions:options];
หากคุณมีเฉพาะโมเดลที่โฮสต์จากระยะไกล คุณควรปิดใช้โมเดลที่เกี่ยวข้องกับ ตัวอย่างเช่น เป็นสีเทาหรือซ่อนบางส่วนของ 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]; }];
2. เตรียมรูปภาพอินพุต
สร้างออบเจ็กต์ 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];
3. เรียกใช้เครื่องมือติดป้ายกำกับรูปภาพ
หากต้องการติดป้ายกำกับวัตถุในรูปภาพ ให้ส่งออบเจ็กต์ image ไปยังออบเจ็กต์ของ ImageLabeler
process() วิธี
ไม่พร้อมกัน:
Swift
imageLabeler.process(image) { labels, error in guard error == nil, let labels = labels, !labels.isEmpty else { // Handle the error. return } // Show results. }
Objective-C
[imageLabeler processImage:image completion:^(NSArray*_Nullable labels, NSError *_Nullable error) { if (label.count == 0) { // Handle the error. return; } // Show results. }];
พร้อมกัน:
Swift
var labels: [ImageLabel] do { labels = try imageLabeler.results(in: image) } catch let error { // Handle the error. return } // Show results.
Objective-C
NSError *error; NSArray*labels = [imageLabeler resultsInImage:image error:&error]; // Show results or handle the error.
4. รับข้อมูลเกี่ยวกับเอนทิตีที่ติดป้ายกำกับ
หากการติดป้ายกำกับรูปภาพสำเร็จ จะแสดงผลอาร์เรย์ของImageLabel ImageLabel แต่ละรายการแสดงถึงสิ่งที่
ติดป้ายกำกับในรูปภาพ คุณสามารถดูคำอธิบายข้อความของแต่ละป้ายกำกับ (ถ้ามี
ข้อมูลเมตาของไฟล์โมเดล TensorFlow Lite) คะแนนความเชื่อมั่น และดัชนี
เช่น
Swift
for label in labels { let labelText = label.text let confidence = label.confidence let index = label.index }
Objective-C
for (MLKImageLabel *label in labels) { NSString *labelText = label.text; float confidence = label.confidence; NSInteger index = label.index; }
เคล็ดลับในการปรับปรุงประสิทธิภาพแบบเรียลไทม์
หากต้องการติดป้ายกำกับรูปภาพในแอปพลิเคชันแบบเรียลไทม์ ให้ทำตามดังนี้ เพื่อให้ได้อัตราเฟรมที่ดีที่สุด
- สำหรับการประมวลผลเฟรมวิดีโอ ให้ใช้ API แบบซิงโครนัสของ
results(in:)ในตัวตรวจจับ โทร เมธอดนี้จาก ของAVCaptureVideoDataOutputSampleBufferDelegatecaptureOutput(_, didOutput:from:)เพื่อให้ได้ผลลัพธ์จากวิดีโอที่ระบุแบบพร้อมกัน เฟรม เก็บ ของAVCaptureVideoDataOutputalwaysDiscardsLateVideoFramesเป็นtrueเพื่อควบคุมการโทรหาตัวตรวจจับ หาก เฟรมวิดีโอจะพร้อมใช้งานขณะที่ตัวตรวจจับทำงานอยู่ เฟรมนั้นจะหายไป - หากคุณใช้เอาต์พุตของเครื่องมือตรวจจับเพื่อวางซ้อนกราฟิก รูปภาพอินพุต รับผลลัพธ์จาก ML Kit ก่อน จากนั้นจึงแสดงผลรูปภาพ ซ้อนทับในขั้นตอนเดียว การทำเช่นนี้จะช่วยให้แสดงผลบนพื้นผิวจอแสดงผล เพียงครั้งเดียวสำหรับแต่ละเฟรมอินพุตที่ประมวลผลแล้ว ดู updatePreviewOverlayViewWithLastFrame ในตัวอย่างการเริ่มต้นอย่างรวดเร็วใน ML Kit