หลังจากที่คุณ ฝึกโมเดลของคุณเองโดยใช้ AutoML Vision Edge แล้ว คุณจะสามารถใช้โมเดลนั้นในแอปของคุณเพื่อติดป้ายกำกับรูปภาพได้
ก่อนที่คุณจะเริ่ม
- หากคุณยังไม่ได้เพิ่ม Firebase ลงในแอปของคุณ ให้ทำตามขั้นตอนใน คู่มือการเริ่มต้นใช้งาน
- รวมไลบรารี ML Kit ไว้ใน Podfile ของคุณ:
pod 'Firebase/MLVision', '6.25.0' pod 'Firebase/MLVisionAutoML', '6.25.0'
หลังจากที่คุณติดตั้งหรืออัปเดต Pod ของโปรเจ็กต์แล้ว อย่าลืมเปิดโปรเจ็กต์ Xcode โดยใช้.xcworkspace
- ในแอปของคุณ ให้นำเข้า Firebase:
สวิฟท์
import Firebase
วัตถุประสงค์-C
@import Firebase;
1. โหลดโมเดล
ML Kit รันโมเดลที่สร้างโดย AutoML บนอุปกรณ์ อย่างไรก็ตาม คุณสามารถกำหนดค่า ML Kit ให้โหลดโมเดลของคุณจากระยะไกลจาก Firebase จากที่จัดเก็บในเครื่อง หรือทั้งสองอย่าง
ด้วยการโฮสต์โมเดลบน Firebase คุณสามารถอัปเดตโมเดลได้โดยไม่ต้องเปิดตัวแอปเวอร์ชันใหม่ และคุณสามารถใช้การกำหนดค่าระยะไกลและการทดสอบ A/B เพื่อให้บริการโมเดลต่างๆ แบบไดนามิกแก่ผู้ใช้กลุ่มต่างๆ
หากคุณเลือกที่จะระบุโมเดลโดยการโฮสต์โมเดลนั้นกับ Firebase เท่านั้น และไม่รวมโมเดลเข้ากับแอปของคุณ คุณสามารถลดขนาดการดาวน์โหลดเริ่มต้นของแอปได้ อย่างไรก็ตาม โปรดทราบว่าหากโมเดลไม่ได้รวมอยู่กับแอปของคุณ ฟังก์ชันการทำงานใดๆ ที่เกี่ยวข้องกับโมเดลจะไม่สามารถใช้งานได้จนกว่าแอปของคุณจะดาวน์โหลดโมเดลเป็นครั้งแรก
เมื่อรวมโมเดลเข้ากับแอป คุณจะมั่นใจได้ว่าฟีเจอร์ ML ของแอปยังคงใช้งานได้เมื่อโมเดลที่โฮสต์โดย Firebase ไม่พร้อมใช้งาน
กำหนดค่าแหล่งที่มาของโมเดลที่โฮสต์โดย Firebase
หากต้องการใช้โมเดลที่โฮสต์ระยะไกล ให้สร้างออบเจ็กต์ AutoMLRemoteModel
โดยระบุชื่อที่คุณกำหนดให้กับโมเดลเมื่อคุณเผยแพร่:
สวิฟท์
let remoteModel = AutoMLRemoteModel(
name: "your_remote_model" // The name you assigned in the Firebase console.
)
วัตถุประสงค์-C
FIRAutoMLRemoteModel *remoteModel = [[FIRAutoMLRemoteModel alloc]
initWithName:@"your_remote_model"]; // The name you assigned in the Firebase console.
จากนั้น เริ่มต้นงานการดาวน์โหลดโมเดล โดยระบุเงื่อนไขที่คุณต้องการอนุญาตให้ดาวน์โหลด หากไม่มีโมเดลดังกล่าวอยู่ในอุปกรณ์ หรือมีเวอร์ชันที่ใหม่กว่า งานจะดาวน์โหลดโมเดลจาก Firebase แบบอะซิงโครนัส:
สวิฟท์
let downloadConditions = ModelDownloadConditions(
allowsCellularAccess: true,
allowsBackgroundDownloading: true
)
let downloadProgress = ModelManager.modelManager().download(
remoteModel,
conditions: downloadConditions
)
วัตถุประสงค์-C
FIRModelDownloadConditions *downloadConditions =
[[FIRModelDownloadConditions alloc] initWithAllowsCellularAccess:YES
allowsBackgroundDownloading:YES];
NSProgress *downloadProgress =
[[FIRModelManager modelManager] downloadRemoteModel:remoteModel
conditions:downloadConditions];
แอพจำนวนมากเริ่มงานดาวน์โหลดด้วยโค้ดเริ่มต้น แต่คุณสามารถทำได้ทุกเมื่อก่อนจำเป็นต้องใช้โมเดล
กำหนดค่าแหล่งที่มาของโมเดลในเครื่อง
หากต้องการรวมโมเดลเข้ากับแอปของคุณ:
- แยกโมเดลและข้อมูลเมตาออกจากไฟล์ zip ที่คุณดาวน์โหลดจากคอนโซล Firebase ลงในโฟลเดอร์:
your_model_directory |____dict.txt |____manifest.json |____model.tflite
ไฟล์ทั้งสามไฟล์ต้องอยู่ในโฟลเดอร์เดียวกัน เราขอแนะนำให้คุณใช้ไฟล์ในขณะที่คุณดาวน์โหลดโดยไม่มีการแก้ไข (รวมถึงชื่อไฟล์ด้วย) - คัดลอกโฟลเดอร์ไปยังโปรเจ็กต์ Xcode ของคุณ โดยเลือก สร้างการอ้างอิงโฟลเดอร์ เมื่อคุณทำเช่นนั้น ไฟล์โมเดลและข้อมูลเมตาจะรวมอยู่ใน App Bundle และพร้อมใช้งานสำหรับ ML Kit
- สร้างออบเจ็กต์
AutoMLLocalModel
โดยระบุเส้นทางไปยังไฟล์รายการโมเดล:สวิฟท์
guard let manifestPath = Bundle.main.path( forResource: "manifest", ofType: "json", inDirectory: "your_model_directory" ) else { return true } let localModel = AutoMLLocalModel(manifestPath: manifestPath)
วัตถุประสงค์-C
NSString *manifestPath = [NSBundle.mainBundle pathForResource:@"manifest" ofType:@"json" inDirectory:@"your_model_directory"]; FIRAutoMLLocalModel *localModel = [[FIRAutoMLLocalModel alloc] initWithManifestPath:manifestPath];
สร้างเครื่องติดป้ายกำกับรูปภาพจากโมเดลของคุณ
หลังจากที่คุณกำหนดค่าแหล่งที่มาของโมเดลแล้ว ให้สร้างออบเจ็กต์ VisionImageLabeler
จากหนึ่งในนั้น
หากคุณมีเฉพาะโมเดลที่รวมอยู่ในเครื่อง เพียงสร้างผู้ติดป้ายกำกับจากออบเจ็กต์ AutoMLLocalModel
ของคุณและกำหนดค่าเกณฑ์คะแนนความเชื่อมั่นที่คุณต้องการ (ดู ประเมินโมเดลของคุณ ):
สวิฟท์
let options = VisionOnDeviceAutoMLImageLabelerOptions(localModel: localModel)
options.confidenceThreshold = 0 // Evaluate your model in the Firebase console
// to determine an appropriate value.
let labeler = Vision.vision().onDeviceAutoMLImageLabeler(options: options)
วัตถุประสงค์-C
FIRVisionOnDeviceAutoMLImageLabelerOptions *options =
[[FIRVisionOnDeviceAutoMLImageLabelerOptions alloc] initWithLocalModel:localModel];
options.confidenceThreshold = 0; // Evaluate your model in the Firebase console
// to determine an appropriate value.
FIRVisionImageLabeler *labeler =
[[FIRVision vision] onDeviceAutoMLImageLabelerWithOptions:options];
หากคุณมีโมเดลที่โฮสต์ระยะไกล คุณจะต้องตรวจสอบว่ามีการดาวน์โหลดก่อนที่จะรัน คุณสามารถตรวจสอบสถานะของงานดาวน์โหลดโมเดลได้โดยใช้เมธอด isModelDownloaded(remoteModel:)
ของตัวจัดการโมเดล
แม้ว่าคุณจะต้องยืนยันสิ่งนี้ก่อนเรียกใช้เครื่องติดป้ายกำกับเท่านั้น หากคุณมีทั้งโมเดลที่โฮสต์จากระยะไกลและโมเดลที่รวมไว้ในเครื่อง ก็อาจเหมาะสมที่จะดำเนินการตรวจสอบนี้เมื่อสร้างอินสแตนซ์ VisionImageLabeler
: สร้างเครื่องติดป้ายกำกับจากโมเดลระยะไกลหาก ได้รับการดาวน์โหลดและจากรุ่นท้องถิ่นเป็นอย่างอื่น
สวิฟท์
var options: VisionOnDeviceAutoMLImageLabelerOptions?
if (ModelManager.modelManager().isModelDownloaded(remoteModel)) {
options = VisionOnDeviceAutoMLImageLabelerOptions(remoteModel: remoteModel)
} else {
options = VisionOnDeviceAutoMLImageLabelerOptions(localModel: localModel)
}
options.confidenceThreshold = 0 // Evaluate your model in the Firebase console
// to determine an appropriate value.
let labeler = Vision.vision().onDeviceAutoMLImageLabeler(options: options)
วัตถุประสงค์-C
VisionOnDeviceAutoMLImageLabelerOptions *options;
if ([[FIRModelManager modelManager] isModelDownloaded:remoteModel]) {
options = [[FIRVisionOnDeviceAutoMLImageLabelerOptions alloc] initWithRemoteModel:remoteModel];
} else {
options = [[FIRVisionOnDeviceAutoMLImageLabelerOptions alloc] initWithLocalModel:localModel];
}
options.confidenceThreshold = 0.0f; // Evaluate your model in the Firebase console
// to determine an appropriate value.
FIRVisionImageLabeler *labeler = [[FIRVision vision] onDeviceAutoMLImageLabelerWithOptions:options];
หากคุณมีเฉพาะโมเดลที่โฮสต์จากระยะไกล คุณควรปิดใช้งานฟังก์ชันที่เกี่ยวข้องกับโมเดล เช่น ทำให้เป็นสีเทาหรือซ่อนบางส่วนของ UI จนกว่าคุณจะยืนยันว่าดาวน์โหลดโมเดลแล้ว
คุณสามารถรับสถานะการดาวน์โหลดโมเดลได้โดยแนบผู้สังเกตการณ์เข้ากับศูนย์การแจ้งเตือนเริ่มต้น ตรวจสอบให้แน่ใจว่าใช้การอ้างอิงถึง self
ที่ไม่ชัดเจนในบล็อกผู้สังเกตการณ์ เนื่องจากการดาวน์โหลดอาจใช้เวลาสักครู่ และวัตถุต้นทางสามารถปล่อยออกได้เมื่อการดาวน์โหลดเสร็จสิ้น ตัวอย่างเช่น:
สวิฟท์
NotificationCenter.default.addObserver( forName: .firebaseMLModelDownloadDidSucceed, 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: .firebaseMLModelDownloadDidFail, 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] // ... }
วัตถุประสงค์-C
__weak typeof(self) weakSelf = self; [NSNotificationCenter.defaultCenter addObserverForName:FIRModelDownloadDidSucceedNotification object:nil queue:nil usingBlock:^(NSNotification *_Nonnull note) { if (weakSelf == nil | note.userInfo == nil) { return; } __strong typeof(self) strongSelf = weakSelf; FIRRemoteModel *model = note.userInfo[FIRModelDownloadUserInfoKeyRemoteModel]; if ([model.name isEqualToString:@"your_remote_model"]) { // The model was downloaded and is available on the device } }]; [NSNotificationCenter.defaultCenter addObserverForName:FIRModelDownloadDidFailNotification object:nil queue:nil usingBlock:^(NSNotification *_Nonnull note) { if (weakSelf == nil | note.userInfo == nil) { return; } __strong typeof(self) strongSelf = weakSelf; NSError *error = note.userInfo[FIRModelDownloadUserInfoKeyError]; }];
2. เตรียมภาพที่นำเข้า
จากนั้น สำหรับแต่ละภาพที่คุณต้องการติดป้ายกำกับ ให้สร้างวัตถุ VisionImage
โดยใช้ตัวเลือกใดตัวเลือกหนึ่งที่อธิบายไว้ในส่วนนี้ และส่งต่อไปยังอินสแตนซ์ของ VisionImageLabeler
(อธิบายไว้ในส่วนถัดไป)
สร้างวัตถุ VisionImage
โดยใช้ UIImage
หรือ CMSampleBufferRef
วิธีใช้ UIImage
:
- หากจำเป็น ให้หมุนรูปภาพเพื่อให้คุณสมบัติ
imageOrientation
เป็น.up
- สร้างวัตถุ
VisionImage
โดยใช้UIImage
ที่หมุนอย่างถูกต้อง อย่าระบุข้อมูลเมตาการหมุนเวียนใดๆ ต้องใช้ค่าเริ่มต้น ..topLeft
สวิฟท์
let image = VisionImage(image: uiImage)
วัตถุประสงค์-C
FIRVisionImage *image = [[FIRVisionImage alloc] initWithImage:uiImage];
วิธีใช้ CMSampleBufferRef
:
สร้างออบเจ็กต์
VisionImageMetadata
ที่ระบุการวางแนวของข้อมูลรูปภาพที่มีอยู่ในบัฟเฟอร์CMSampleBufferRef
เพื่อให้ได้การวางแนวของภาพ:
สวิฟท์
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 } }
วัตถุประสงค์-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; } }
จากนั้นสร้างวัตถุข้อมูลเมตา:
สวิฟท์
let cameraPosition = AVCaptureDevice.Position.back // Set to the capture device you used. let metadata = VisionImageMetadata() metadata.orientation = imageOrientation( deviceOrientation: UIDevice.current.orientation, cameraPosition: cameraPosition )
วัตถุประสงค์-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];
- สร้างวัตถุ
VisionImage
โดยใช้วัตถุCMSampleBufferRef
และข้อมูลเมตาการหมุน:สวิฟท์
let image = VisionImage(buffer: sampleBuffer) image.metadata = metadata
วัตถุประสงค์-C
FIRVisionImage *image = [[FIRVisionImage alloc] initWithBuffer:sampleBuffer]; image.metadata = metadata;
3. เรียกใช้ตัวติดป้ายกำกับรูปภาพ
หากต้องการติดป้ายกำกับวัตถุในรูปภาพ ให้ส่งวัตถุ VisionImage
ไปยังเมธอด process()
ของ VisionImageLabeler
:
สวิฟท์
labeler.process(image) { labels, error in
guard error == nil, let labels = labels else { return }
// Task succeeded.
// ...
}
วัตถุประสงค์-C
[labeler
processImage:image
completion:^(NSArray<FIRVisionImageLabel *> *_Nullable labels, NSError *_Nullable error) {
if (error != nil || labels == nil) {
return;
}
// Task succeeded.
// ...
}];
หากการติดป้ายกำกับรูปภาพสำเร็จ อาร์เรย์ของออบเจ็กต์ VisionImageLabel
จะถูกส่งไปยังตัวจัดการการทำให้เสร็จสมบูรณ์ จากแต่ละออบเจ็กต์ คุณสามารถรับข้อมูลเกี่ยวกับคุณลักษณะที่จดจำได้ในรูปภาพ
ตัวอย่างเช่น:
สวิฟท์
for label in labels {
let labelText = label.text
let confidence = label.confidence
}
วัตถุประสงค์-C
for (FIRVisionImageLabel *label in labels) {
NSString *labelText = label.text;
NSNumber *confidence = label.confidence;
}
เคล็ดลับในการปรับปรุงประสิทธิภาพแบบเรียลไทม์
- คันเร่งเรียกไปที่เครื่องตรวจจับ หากมีเฟรมวิดีโอใหม่ในขณะที่ตัวตรวจจับกำลังทำงานอยู่ ให้ปล่อยเฟรมนั้น
- หากคุณใช้เอาต์พุตของตัวตรวจจับเพื่อวางซ้อนกราฟิกบนรูปภาพอินพุต อันดับแรกรับผลลัพธ์จาก ML Kit จากนั้นเรนเดอร์รูปภาพและโอเวอร์เลย์ในขั้นตอนเดียว การทำเช่นนี้ คุณจะเรนเดอร์ไปยังพื้นผิวจอแสดงผลเพียงครั้งเดียวสำหรับแต่ละเฟรมอินพุต ดูตัวอย่างคลาส PreviewOverlayView และ FIRDetectionOverlayView ในแอปตัวอย่าง Showcase