میتوانید از ML Kit برای تشخیص نهادها در تصویر و برچسبگذاری آنها استفاده کنید. این میانای برنامهسازی کاربردی از طیف وسیعی از مدلهای طبقهبندی تصویر سفارشی پشتیبانی میکند. برای راهنمایی درباره الزامات سازگاری مدل، مکان یافتن مدلهای ازپیش آموزشدیده، و نحوه آموزش مدلهای خودتان، به مدلهای سفارشی با ML Kit مراجعه کنید.
دو روش برای یکپارچه کردن مدل سفارشی وجود دارد. میتوانید مدل را با قرار دادن آن در پوشه دارایی برنامهتان بستهبندی کنید، یا میتوانید آن را بهطور پویا از Cloud Storage بارگیری کنید. جدول زیر این دو گزینه را مقایسه میکند.
| مدل بستهای | مدل میزبانیشده |
|---|---|
| این مدل بخشی از فایل APK برنامه شما است که باعث افزایش حجم آن میشود. | مدل بخشی از APK شما نیست. با بارگذاری در Cloud Storage میزبانی میشود. توصیه میکنیم از Cloud Storage for Firebase استفاده کنید. |
| این مدل بلافاصله دردسترس است، حتی وقتی دستگاه Android آفلاین باشد | برنامهتان باید حاوی کد برای بارگیری مدل درصورت نیاز باشد |
| نیازی به پروژه Firebase نیست | به پروژه Firebase نیاز دارد (درصورت استفاده از Cloud Storage for Firebase). |
| برای بهروزرسانی مدل باید برنامهتان را دوباره منتشر کنید | بهروزرسانیهای مدل را بدون بازانتشار برنامه خود ارسال کنید |
| آزمون آ/ب داخلی ندارد | آزمون آ/ب با پیکربندی از راه دور Firebase |
امتحان کنید
- برای نمونهای از استفاده از مدل دستهای و برنامه شروع سریع automl برای نمونهای از استفاده از مدل میزبانیشده، برنامه شروع سریع دیداری را ببینید.
قبلاز شروع
کتابخانههای ML Kit را در Podfile خود بگنجانید:
pod 'GoogleMLKit/ImageLabelingCustom', '8.0.0'پساز نصب یا بهروزرسانی Pods پروژهتان، پروژه Xcode را بااستفاده از
.xcworkspaceآن باز کنید. ML Kit در Xcode نسخه ۱۳.۲.۱ یا بالاتر پشتیبانی میشود.اگر میخواهید مدلی را بااستفاده از «فضای ذخیرهسازی ابری ویژه Firebase» بارگیری کنید، مطمئن شوید که Firebase را به پروژه iOS خود اضافه کردهاید، اگر قبلاً این کار را نکردهاید. این کار هنگام بستهبندی مدل لازم نیست.
۱. بار کردن مدل
پیکربندی منبع مدل محلی
برای بستهبندی کردن مدل با برنامهتان:
فایل مدل (معمولاً با
.tfliteیا.liteتمام میشود) را در پروژه Xcode کپی کنید و هنگام انجام این کار،Copy bundle resourcesرا انتخاب کنید. فایل مدل در بسته برنامه گنجانده میشود و برای ML Kit دردسترس خواهد بود.با مشخص کردن مسیر فایل مدل، شیء
LocalModelرا ایجاد کنید:Swift
let localModel = LocalModel(path: localModelFilePath)
آبجکتیو-سی
MLKLocalModel *localModel = [[MLKLocalModel alloc] initWithPath:localModelFilePath];
پیکربندی منبع مدل میزبانیشده از راه دور
برای استفاده از مدل میزبانیشده از راه دور، باید فایل مدل را بااستفاده از منطق برنامه خودتان در فضای ذخیرهسازی محلی دستگاه بارگیری کنید و سپس آن را بهعنوان مدل محلی بار کنید. توصیه میکنیم از Cloud Storage for Firebase برای میزبانی مدل استفاده کنید. برای جزئیات پیادهسازی، راهنمای انتقال Firebase ML به Cloud Storage را ببینید.
پیکربندی برچسبزن تصویر
پساز پیکربندی منابع مدل، از یکی از آنها شیء ImageLabeler ایجاد کنید.
گزینههای زیر دردسترس است:
| گزینهها | |
|---|---|
confidenceThreshold
|
حداقل امتیاز اطمینان برچسبهای شناساییشده. اگر تنظیم نشده باشد، از هر آستانه طبقهبندی مشخصشده توسط فراداده مدل استفاده خواهد شد. اگر مدل هیچ فرادادهای نداشته باشد یا فراداده آستانه طبقهبندی را مشخص نکند، از آستانه پیشفرض ۰٫۰ استفاده خواهد شد. |
maxResultCount
|
حداکثر تعداد برچسبها برای برگرداندن. اگر تنظیم نشده باشد، از مقدار پیشفرض ۱۰ استفاده خواهد شد. |
اگر فقط مدل دستهبندی محلی دارید، کافی است از
LocalModel شیء خود یک برچسبزن ایجاد کنید:
Swift
let options = CustomImageLabelerOptions(localModel: localModel) options.confidenceThreshold = NSNumber(value: 0.0) let imageLabeler = ImageLabeler.imageLabeler(options: options)
آبجکتیو-سی
MLKCustomImageLabelerOptions *options = [[MLKCustomImageLabelerOptions alloc] initWithLocalModel:localModel]; options.confidenceThreshold = @(0.0); MLKImageLabeler *imageLabeler = [MLKImageLabeler imageLabelerWithOptions:options];
اگر مدل با میزبانی از راه دور دارید، باید قبلاز اجرای آن بررسی کنید که بارگیری شده باشد.
اگرچه فقط باید این را قبلاز اجرای برچسبزن تأیید کنید، اگر هم مدل میزبانیشده از راه دور و هم مدل بستهبندیشده محلی دارید، ممکن است منطقی باشد که این بررسی را هنگام نمونهسازی ImageLabeler انجام دهید: اگر مدل از راه دور بارگیری شده است، برچسبزن را از آن ایجاد کنید، و درغیراینصورت از مدل محلی ایجاد کنید.
Swift
// Path where your download logic saves the model let documentDirectory = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first! let localModelURL = documentDirectory.appendingPathComponent("my_remote_model.tflite") let model: LocalModel if FileManager.default.fileExists(atPath: localModelURL.path) { // Use the downloaded model model = LocalModel(path: localModelURL.path) } else { // Fall back to bundled model guard let bundledModelPath = Bundle.main.path(forResource: "model", ofType: "tflite") else { return } model = LocalModel(path: bundledModelPath) } let options = CustomImageLabelerOptions(localModel: model) let imageLabeler = ImageLabeler.imageLabeler(options: options)
آبجکتیو-سی
NSString *documentsDirectory = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) firstObject]; NSString *localModelPath = [documentsDirectory stringByAppendingPathComponent:@"my_remote_model.tflite"]; MLKLocalModel *model; if ([NSFileManager.defaultManager fileExistsAtPath:localModelPath]) { // Use the downloaded model model = [[MLKLocalModel alloc] initWithPath:localModelPath]; } else { // Fall back to bundled model NSString *bundledModelPath = [NSBundle.mainBundle pathForResource:@"model" ofType:@"tflite"]; model = [[MLKLocalModel alloc] initWithPath:bundledModelPath]; } MLKCustomImageLabelerOptions *options = [[MLKCustomImageLabelerOptions alloc] initWithLocalModel:model]; MLKImageLabeler *imageLabeler = [MLKImageLabeler imageLabelerWithOptions:options];
اگر فقط مدل میزبانیشده ازراهدور دارید، باید عملکرد مربوط به مدل را غیرفعال کنید (برای مثال، بخشی از میانای کاربر را خاکستری یا پنهان کنید) تا زمانی که تأیید کنید مدل بارگیری شده است.
Swift
let documentDirectory = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first! let localModelURL = documentDirectory.appendingPathComponent("my_remote_model.tflite") if FileManager.default.fileExists(atPath: localModelURL.path) { // Model is already cached, initialize immediately self.initializeLabeler(with: localModelURL) } else { // Model is not yet available, show loading UI and start download self.showLoadingUI() let storage = Storage.storage() let modelRef = storage.reference(forURL: "gs://YOUR_BUCKET/path/to/model.tflite") modelRef.write(toFile: localModelURL) { url, error in self.hideLoadingUI() if let error = error { // Handle download error self.showErrorUI() } else if let modelURL = url { // Download success, initialize labeler self.initializeLabeler(with: modelURL) } } } func initializeLabeler(with modelURL: URL) { let localModel = LocalModel(path: modelURL.path) let options = CustomImageLabelerOptions(localModel: localModel) self.imageLabeler = ImageLabeler.imageLabeler(options: options) // Enable ML-related UI features here self.enableMLFeatures() }
آبجکتیو-سی
NSString *documentsDirectory = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) firstObject]; NSString *localModelPath = [documentsDirectory stringByAppendingPathComponent:@"my_remote_model.tflite"]; NSURL *localModelURL = [NSURL fileURLWithPath:localModelPath]; if ([NSFileManager.defaultManager fileExistsAtPath:localModelPath]) { // Model is already cached, initialize immediately [self initializeLabelerWithURL:localModelURL]; } else { // Model is not yet available, show loading UI and start download [self showLoadingUI]; FIRStorage *storage = [FIRStorage storage]; FIRStorageReference *modelRef = [storage referenceForURL:@"gs://YOUR_BUCKET/path/to/model.tflite"]; [modelRef writeToFile:localModelURL completion:^(NSURL * _Nullable URL, NSError * _Nullable error) { [self hideLoadingUI]; if (error != nil) { // Handle download error [self showErrorUI]; } else { // Download success, initialize labeler [self initializeLabelerWithURL:URL]; } }]; } - (void)initializeLabelerWithURL:(NSURL *)modelURL { MLKLocalModel *localModel = [[MLKLocalModel alloc] initWithPath:modelURL.path]; MLKCustomImageLabelerOptions *options = [[MLKCustomImageLabelerOptions alloc] initWithLocalModel:localModel]; self.imageLabeler = [MLKImageLabeler imageLabelerWithOptions:options]; // Enable ML-related UI features here [self enableMLFeatures]; }
۲. آماده کردن تصویر ورودی
بااستفاده از UIImage یا CMSampleBuffer، یک شیء VisionImage ایجاد کنید.
اگر از UIImage استفاده میکنید، این مراحل را دنبال کنید:
- یک شیء
VisionImageباUIImageایجاد کن. حتماً.orientationصحیح را مشخص کنید.Swift
let image = VisionImage(image: UIImage) visionImage.orientation = image.imageOrientation
آبجکتیو-سی
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 } }
آبجکتیو-سی
- (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; } }
- بااستفاده از شیء
CMSampleBufferو جهت، شیءVisionImageایجاد کنید:Swift
let image = VisionImage(buffer: sampleBuffer) image.orientation = imageOrientation( deviceOrientation: UIDevice.current.orientation, cameraPosition: cameraPosition)
آبجکتیو-سی
MLKVisionImage *image = [[MLKVisionImage alloc] initWithBuffer:sampleBuffer]; image.orientation = [self imageOrientationFromDeviceOrientation:UIDevice.currentDevice.orientation cameraPosition:cameraPosition];
۳. اجرای برچسبزن تصویر
برای برچسبگذاری اشیاء در تصویر، شیء image را به روش process()
ImageLabeler ارسال کنید.
ناهمگام:
Swift
imageLabeler.process(image) { labels, error in guard error == nil, let labels = labels, !labels.isEmpty else { // Handle the error. return } // Show results. }
آبجکتیو-سی
[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.
آبجکتیو-سی
NSError *error; NSArray*labels = [imageLabeler resultsInImage:image error:&error]; // Show results or handle the error.
۴. دریافت اطلاعات درباره نهادهای برچسبگذاریشده
اگر عملیات برچسبگذاری تصویر موفق باشد، آرایهای ازImageLabel برمیگرداند. هر ImageLabel نشاندهنده چیزی است که در تصویر
برچسبگذاری شده است. میتوانید شرح نوشتاری هر برچسب (درصورت وجود در فراداده فایل مدل LiteRT)، امتیاز اطمینان، و نمایهاش را دریافت کنید. برای مثال:
Swift
for label in labels { let labelText = label.text let confidence = label.confidence let index = label.index }
آبجکتیو-سی
for (MLKImageLabel *label in labels) { NSString *labelText = label.text; float confidence = label.confidence; NSInteger index = label.index; }
نکتههایی برای بهبود عملکرد همزمان
اگر میخواهید تصاویر را در یک برنامه همزمان برچسبگذاری کنید، این دستورالعملها را برای دستیابی به بهترین نرخهای فریم دنبال کنید:
- برای پردازش فریمهای ویدیو، از میانای برنامهسازی کاربردی همگام
results(in:)آشکارساز استفاده کنید. این روش را از تابعcaptureOutput(_, didOutput:from:)مربوط بهAVCaptureVideoDataOutputSampleBufferDelegateفراخوانی کنید تا نتایج را بهصورت همگام از فریم ویدیو دادهشده دریافت کنید.AVCaptureVideoDataOutputalwaysDiscardsLateVideoFramesرا بهعنوانtrueنگه دارید تا تماسها با آشکارساز را محدود کنید. اگر قاب ویدیو جدیدی درحین اجرای آشکارساز دردسترس قرار گیرد، حذف خواهد شد. - اگر از برونداد آشکارساز برای رونهادن گرافیک روی تصویر ورودی استفاده میکنید، ابتدا نتیجه را از ML Kit دریافت کنید، سپس تصویر را پرداز و در یک مرحله رونهاد کنید. با انجام این کار، برای هر قاب ورودی پردازششده، فقط یکبار به سطح نمایشگر رندر میکنید. برای نمونه، updatePreviewOverlayViewWithLastFrame را در نمونه راهاندازی سریع ML Kit ببینید.