وقتی تصویری را به ML Kit میدهید، این کیت حداکثر پنج شیء را در تصویر بههمراه موقعیت هر شیء در تصویر تشخیص میدهد. هنگام شناسایی اشیاء در جاریسازیهای ویدیویی، هر شیء شناسه یکتایی دارد که میتوانید از آن برای ردیابی شیء از فریمی به فریم دیگر استفاده کنید.
میتوانید از مدل طبقهبندی تصویر سفارشی برای طبقهبندی کردن اشیایی که شناسایی میشوند استفاده کنید. برای راهنمایی درباره الزامات سازگاری مدل، مکان یافتن مدلهای ازپیش آموزشدیده، و نحوه آموزش مدلهای خودتان، به مدلهای سفارشی با ML Kit مراجعه کنید.
دو روش برای یکپارچه کردن مدل سفارشی وجود دارد. میتوانید مدل را با قرار دادن آن در پوشه دارایی برنامهتان بستهبندی کنید، یا میتوانید آن را بهطور پویا از Cloud Storage بارگیری کنید. جدول زیر این دو گزینه را مقایسه میکند.
| مدل بستهای | مدل میزبانیشده |
|---|---|
این مدل بخشی از فایل .ipa برنامه شما است که
اندازه آن را افزایش میدهد. |
این مدل بخشی از فایل .ipa برنامهتان نیست. این برنامه با بارگذاری در Cloud Storage میزبانی میشود. توصیه میکنیم از
Cloud Storage for
Firebase استفاده کنید. |
| مدل فوراً دردسترس قرار میگیرد، حتی وقتی دستگاه Android آفلاین باشد | برنامهتان باید حاوی کدی برای بارگیری مدل درصورت درخواست باشد |
| نیازی به پروژه Firebase نیست | به پروژه Firebase نیاز دارد (اگر از «فضای ذخیرهسازی ابری ویژه Firebase» استفاده میکنید). |
| برای بهروزرسانی مدل باید برنامهتان را دوباره منتشر کنید | بهروزرسانیهای مدل را بدون انتشار مجدد برنامهتان ارسال کنید |
| نداشتن آزمایش آ/ب داخلی | آزمون آ/ب با پیکربندی از راه دور Firebase |
امتحان کنید
- برای نمونهای از کاربرد مدل بستهای، برنامه شروع سریع Vision را ببینید و برای نمونهای از کاربرد مدل میزبانیشده، برنامه شروع سریع AutoML را ببینید.
- برای پیادهسازی سرتاسری این API، به برنامه ویترین Material Design مراجعه کنید.
قبلاز شروع
کتابخانههای ML Kit را در Podfile خود اضافه کنید:
pod 'GoogleMLKit/ObjectDetectionCustom', '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 را ببینید.
۲. پیکربندی آشکارساز شیء
پساز پیکربندی منابع مدل، آشکارساز شیء را برای مورد استفادهتان با شیء CustomObjectDetectorOptions پیکربندی کنید. میتوانید تنظیمات زیر را تغییر دهید:
| تنظیمات آشکارساز اشیا | |
|---|---|
| حالت تشخیص |
STREAM_MODE (پیشفرض) | SINGLE_IMAGE_MODE
در در |
| شناسایی و ردیابی چند شیء |
false (پیشفرض) | true
اینکه حداکثر پنج شیء یا فقط برجستهترین شیء (پیشفرض) شناسایی و ردیابی شود. |
| طبقهبندی اشیاء |
false (پیشفرض) | true
اینکه آیا اشیای شناساییشده بااستفاده از مدل طبقهبند سفارشی ارائهشده طبقهبندی شوند یا نه. برای استفاده از مدل طبقهبندی سفارشیتان،
باید این را روی |
| آستانه اطمینان طبقهبندی |
حداقل امتیاز اطمینان برچسبهای شناساییشده. اگر تنظیم نشده باشد، از هر آستانه طبقهبندیکنندهای که توسط فراداده مدل مشخص شده است استفاده خواهد شد. اگر مدل هیچ فرادادهای نداشته باشد یا فراداده آستانه طبقهبندی را مشخص نکند، از آستانه پیشفرض ۰٫۰ استفاده خواهد شد. |
| حداکثر برچسبها برای هر شیء |
حداکثر تعداد برچسبها برای هر شیء که آشکارساز برمیگرداند. اگر تنظیم نشود، از مقدار پیشفرض ۱۰ استفاده خواهد شد. |
اگر فقط مدل دستهبندی محلی دارید، کافی است آشکارساز شیء را از
شیء 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
آبجکتیو-سی
MLKCustomObjectDetectorOptions *options = [[MLKCustomObjectDetectorOptions alloc] initWithLocalModel:localModel]; options.detectorMode = MLKObjectDetectorModeSingleImage; options.shouldEnableClassification = YES; options.shouldEnableMultipleObjects = YES; options.classificationConfidenceThreshold = @(0.5); options.maxPerObjectLabelCount = 3;
اگر مدل از دور میزبانی میشود، باید بررسی کنید که قبلاز اجرا شدن بارگیری شده باشد.
اگرچه فقط باید این موضوع را قبلاز اجرای آشکارساز شیء تأیید کنید، اما اگر هم مدل میزبانیشده از راه دور و هم مدل بستهبندیشده محلی دارید، ممکن است منطقی باشد که این بررسی را هنگام نمونهسازی ObjectDetector انجام دهید: اگر مدل از راه دور بارگیری شده است، یک آشکارساز از آن ایجاد کنید و درغیراینصورت از مدل محلی استفاده کنید.
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 = CustomObjectDetectorOptions(localModel: model) options.detectorMode = .singleImage options.shouldEnableClassification = true options.shouldEnableMultipleObjects = true options.classificationConfidenceThreshold = NSNumber(value: 0.5) options.maxPerObjectLabelCount = 3 let objectDetector = ObjectDetector.objectDetector(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]; } MLKCustomObjectDetectorOptions *options = [[MLKCustomObjectDetectorOptions alloc] initWithLocalModel:model]; options.detectorMode = MLKObjectDetectorModeSingleImage; options.shouldEnableClassification = YES; options.shouldEnableMultipleObjects = YES; options.classificationConfidenceThreshold = @(0.5); options.maxPerObjectLabelCount = 3; MLKObjectDetector *objectDetector = [MLKObjectDetector objectDetectorWithOptions: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.initializeDetector(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 detector self.initializeDetector(with: modelURL) } } } func initializeDetector(with modelURL: URL) { let localModel = LocalModel(path: modelURL.path) let options = CustomObjectDetectorOptions(localModel: localModel) options.detectorMode = .singleImage options.shouldEnableClassification = true options.shouldEnableMultipleObjects = true self.objectDetector = ObjectDetector.objectDetector(options: options) // Enable ML features in UI 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 initializeDetectorWithURL: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 detector [self initializeDetectorWithURL:URL]; } }]; } - (void)initializeDetectorWithURL:(NSURL *)modelURL { MLKLocalModel *localModel = [[MLKLocalModel alloc] initWithPath:modelURL.path]; MLKCustomObjectDetectorOptions *options = [[MLKCustomObjectDetectorOptions alloc] initWithLocalModel:localModel]; options.detectorMode = MLKObjectDetectorModeSingleImage; options.shouldEnableClassification = YES; options.shouldEnableMultipleObjects = YES; self.objectDetector = [MLKObjectDetector objectDetectorWithOptions:options]; // Enable ML features in UI [self enableMLFeatures]; }
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
آبجکتیو-سی
// 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;
۳. آماده کردن تصویر ورودی
بااستفاده از 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];
۴. ایجاد و اجرای آشکارساز شیء
ایجاد آشکارساز شیء جدید:
Swift
let objectDetector = ObjectDetector.objectDetector(options: options)
آبجکتیو-سی
MLKObjectDetector *objectDetector = [MLKObjectDetector objectDetectorWithOptions:options];
سپس، از آشکارساز استفاده کنید:
ناهمگام:
Swift
objectDetector.process(image) { objects, error in guard error == nil, let objects = objects, !objects.isEmpty else { // Handle the error. return } // Show results. }
آبجکتیو-سی
[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.
آبجکتیو-سی
NSError *error; NSArray
*objects = [objectDetector resultsInImage:image error:&error]; // Show results or handle the error.
۵. دریافت اطلاعات درباره اشیای برچسبگذاریشده
اگر تماس با پردازشگر تصویر موفقیتآمیز باشد، بسته به اینکه روش ناهمزمان یا همزمان را فراخوانی کردهاید، یا فهرست
Objects را به کنترلکننده تکمیل ارسال میکند یا فهرست را برمیگرداند.
هر Object شامل ویژگیهای زیر است:
frame |
CGRect که موقعیت شیء را در تصویر نشان میدهد. |
||||||
trackingID |
عدد صحیحی که شیء را در تصاویر شناسایی میکند، یا `nil` در SINGLE_IMAGE_MODE. | ||||||
labels |
|
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") }
آبجکتیو-سی
// 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 و مجموعه الگوهای ویژگیهای مجهز به یادگیری ماشین Material Design را بررسی کنید.
بهبود عملکرد
اگر میخواهید از تشخیص اشیا در برنامه همزمان استفاده کنید، این دستورالعملها را دنبال کنید تا به بهترین نرخهای فریم دست یابید:وقتی از حالت جاریسازی در یک برنامه همزمان استفاده میکنید، از تشخیص چندگانه شیء استفاده نکنید، زیرا اکثر دستگاهها نمیتوانند نرخ فریم کافی تولید کنند.
- برای پردازش قابهای ویدیو، از
results(in:)میانای برنامهسازی کاربردی همزمان آشکارساز استفاده کنید. این روش را از تابعcaptureOutput(_, didOutput:from:)مربوط بهAVCaptureVideoDataOutputSampleBufferDelegateفراخوانی کنید تا نتایج را بهصورت همگام از فریم ویدیو دادهشده دریافت کنید.AVCaptureVideoDataOutputalwaysDiscardsLateVideoFramesرا بهعنوانtrueنگه دارید تا تماسها با آشکارساز را محدود کنید. اگر درحین اجرای آشکارساز، فریم ویدیویی جدیدی دردسترس قرار گیرد، آن فریم حذف خواهد شد. - اگر از خروجی آشکارساز برای همپوشانی گرافیک روی تصویر ورودی استفاده میکنید، ابتدا نتیجه را از ML Kit دریافت کنید، سپس تصویر و همپوشانی را در یک مرحله رندر کنید. با انجام این کار، برای هر قاب ورودی پردازششده، فقط یکبار به سطح نمایشگر رندر میکنید. برای نمونه، updatePreviewOverlayViewWithLastFrame را در نمونه راهاندازی سریع ML Kit ببینید.