หลังจากที่คุณฝึกโมเดลของคุณเองโดยใช้ AutoML Vision Edge ก็ใช้ในแอปเพื่อติดป้ายกำกับรูปภาพได้
การผสานรวมโมเดลที่ฝึกจาก AutoML Vision Edge ทำได้ 2 วิธี คุณสามารถ รวมโมเดลโดยคัดลอกไฟล์ของโมเดลลงในโปรเจ็กต์ Xcode ของคุณ หรือคุณ จะสามารถดาวน์โหลดแบบไดนามิกจาก Firebase
ตัวเลือกการรวมโมเดล | |
---|---|
รวมอยู่ในแอป |
|
โฮสต์กับ Firebase |
|
ก่อนเริ่มต้น
ใส่คลัง ML Kit ใน Podfile
สำหรับการรวมโมเดลกับแอป ให้ทำดังนี้
pod 'GoogleMLKit/ImageLabelingCustom'
สำหรับการดาวน์โหลดโมเดลแบบไดนามิกจาก Firebase ให้เพิ่ม
LinkFirebase
การพึ่งพา:pod 'GoogleMLKit/ImageLabelingCustom' pod 'GoogleMLKit/LinkFirebase'
หลังจากติดตั้งหรืออัปเดต Pods ของโปรเจ็กต์แล้ว ให้เปิดโปรเจ็กต์ Xcode โดยใช้
.xcworkspace
ML Kit รองรับ Xcode เวอร์ชัน 12.2 หรือ สูงขึ้นหากต้องการดาวน์โหลดโมเดล โปรดตรวจสอบว่า เพิ่ม Firebase ลงในโปรเจ็กต์ Android หากคุณยังไม่ได้ดำเนินการ ไม่จำเป็นต้องทำขั้นตอนนี้เมื่อคุณรวมชุด โมเดล
1. โหลดโมเดล
กำหนดค่าต้นทางของโมเดลในเครื่อง
วิธีการรวมโมเดลกับแอปมีดังนี้
แยกโมเดลและข้อมูลเมตาของโมเดลจากชุดไฟล์ Zip ที่คุณดาวน์โหลด จากคอนโซล Firebase ลงในโฟลเดอร์:
your_model_directory |____dict.txt |____manifest.json |____model.tflite
ทั้ง 3 ไฟล์ต้องอยู่ในโฟลเดอร์เดียวกัน เราขอแนะนำให้คุณใช้ไฟล์ ขณะที่คุณดาวน์โหลด โดยไม่ต้องแก้ไข (รวมถึงชื่อไฟล์)
คัดลอกโฟลเดอร์ไปยังโปรเจ็กต์ Xcode แล้วเลือก โปรดสร้างการอ้างอิงโฟลเดอร์เมื่อคุณสร้าง ไฟล์โมเดลและข้อมูลเมตา จะรวมอยู่ใน App Bundle และพร้อมใช้งานสำหรับ ML Kit
สร้างออบเจ็กต์
LocalModel
โดยระบุเส้นทางไปยัง ไฟล์ Manifest ของโมเดล:Swift
guard let manifestPath = Bundle.main.path( forResource: "manifest", ofType: "json", inDirectory: "your_model_directory" ) else { return true } let localModel = LocalModel(manifestPath: manifestPath)
Objective-C
NSString *manifestPath = [NSBundle.mainBundle pathForResource:@"manifest" ofType:@"json" inDirectory:@"your_model_directory"]; MLKLocalModel *localModel = [[MLKLocalModel alloc] initWithManifestPath:manifestPath];
กำหนดค่าแหล่งที่มาของโมเดลที่โฮสต์กับ Firebase
หากต้องการใช้โมเดลที่โฮสต์จากระยะไกล ให้สร้าง CustomRemoteModel
โดยระบุชื่อที่คุณกำหนดโมเดลเมื่อเผยแพร่:
Swift
// Initialize the model source with the name you assigned in
// the Firebase console.
let remoteModelSource = FirebaseModelSource(name: "your_remote_model")
let remoteModel = CustomRemoteModel(remoteModelSource: remoteModelSource)
Objective-C
// Initialize the model source with the name you assigned in
// the Firebase console.
MLKFirebaseModelSource *firebaseModelSource =
[[MLKFirebaseModelSource alloc] initWithName:@"your_remote_model"];
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] downloadRemoteModel:remoteModel
conditions:downloadConditions];
แอปจำนวนมากเริ่มงานดาวน์โหลดในโค้ดเริ่มต้น แต่คุณ จากนั้นคุณจะสามารถทำได้ทุกเมื่อก่อนที่จะต้องใช้โมเดลนี้
สร้างเครื่องมือติดป้ายกำกับรูปภาพจากโมเดล
หลังจากกำหนดค่าแหล่งที่มาของโมเดลแล้ว ให้สร้างออบเจ็กต์ ImageLabeler
จาก 1 รายการ
ทั้งหมด
หากคุณมีเฉพาะโมเดลที่รวมภายในเครื่อง ให้สร้างผู้ติดป้ายกำกับจาก
LocalModel
และกำหนดค่าคะแนนความเชื่อมั่น
เกณฑ์ที่ต้องการกำหนด (ดูประเมินโมเดลของคุณ)
Swift
let options = CustomImageLabelerOptions(localModel: localModel)
options.confidenceThreshold = NSNumber(value: 0.0) // Evaluate your model in the Cloud console
// to determine an appropriate value.
let imageLabeler = ImageLabeler.imageLabeler(options)
Objective-C
CustomImageLabelerOptions *options =
[[CustomImageLabelerOptions alloc] initWithLocalModel:localModel];
options.confidenceThreshold = @(0.0f); // Evaluate your model in the Cloud console
// to determine an appropriate value.
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) // Evaluate your model in the Firebase console
// to determine an appropriate value.
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.0f); // Evaluate your model in the Firebase console
// to determine an appropriate value.
MLKImageLabeler *imageLabeler =
[MLKImageLabeler imageLabelerWithOptions:options];
หากคุณมีเฉพาะโมเดลที่โฮสต์จากระยะไกล คุณควรปิดใช้โมเดลที่เกี่ยวข้องกับ ตัวอย่างเช่น เป็นสีเทาหรือซ่อนบางส่วนของ UI จนถึง คุณยืนยันว่าดาวน์โหลดโมเดลแล้ว
คุณดูสถานะการดาวน์โหลดโมเดลได้โดยแนบผู้สังเกตการณ์กับศูนย์การแจ้งเตือนเริ่มต้น โปรดใช้การอ้างอิงที่ไม่รัดกุมไปยัง self
ในผู้สังเกตการณ์
บล็อก เนื่องจากการดาวน์โหลดอาจใช้เวลาสักครู่ และออบเจ็กต์เริ่มต้นอาจ
เมื่อการดาวน์โหลดเสร็จสิ้น เช่น
Swift
NotificationCenter.default.addObserver(
forName: .mlkitMLModelDownloadDidSucceed,
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: .mlkitMLModelDownloadDidFail,
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
หรือ CMSampleBufferRef
หากคุณใช้ 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;
หากคุณใช้ CMSampleBufferRef
ให้ทำตามขั้นตอนต่อไปนี้
-
ระบุการวางแนวของข้อมูลภาพที่มีอยู่ใน บัฟเฟอร์
CMSampleBufferRef
วิธีดูการวางแนวรูปภาพ
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 position == AVCaptureDevicePositionFront ? UIImageOrientationLeftMirrored : UIImageOrientationRight; case UIDeviceOrientationLandscapeLeft: return position == AVCaptureDevicePositionFront ? UIImageOrientationDownMirrored : UIImageOrientationUp; case UIDeviceOrientationPortraitUpsideDown: return position == AVCaptureDevicePositionFront ? UIImageOrientationRightMirrored : UIImageOrientationLeft; case UIDeviceOrientationLandscapeRight: return position == AVCaptureDevicePositionFront ? UIImageOrientationUpMirrored : UIImageOrientationDown; case UIDeviceOrientationUnknown: case UIDeviceOrientationFaceUp: case UIDeviceOrientationFaceDown: return UIImageOrientationUp; } }
- สร้างออบเจ็กต์
VisionImage
โดยใช้ออบเจ็กต์CMSampleBufferRef
และการวางแนวต่อไปนี้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. เรียกใช้เครื่องมือติดป้ายกำกับรูปภาพ
ไม่พร้อมกัน:
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<MLKImageLabel *> *_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<MLKImageLabel *> *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;
}
เคล็ดลับในการปรับปรุงประสิทธิภาพแบบเรียลไทม์
หากต้องการติดป้ายกำกับรูปภาพในแอปพลิเคชันแบบเรียลไทม์ ให้ทำตามดังนี้ เพื่อให้ได้อัตราเฟรมที่ดีที่สุด
- กดควบคุมการโทรหาตัวตรวจจับ หากเฟรมวิดีโอใหม่กลายเป็น วางเฟรมได้ในขณะที่ตัวตรวจจับกำลังทำงานอยู่
- หากคุณใช้เอาต์พุตของเครื่องมือตรวจจับเพื่อวางกราฟิกซ้อนทับบนรูปภาพอินพุต ให้รับผลลัพธ์ก่อน จากนั้นจึงแสดงผลรูปภาพและวางซ้อนในขั้นตอนเดียว การดำเนินการดังกล่าวจะแสดงบนพื้นผิวจอแสดงผล เพียงครั้งเดียวสำหรับเฟรมอินพุตแต่ละเฟรม โปรดดู previewOverlayView และ FIRDetectionOverlayView ในตัวอย่างแอป Showcase