ML Kit دو کیت توسعه نرمافزار بهینهسازیشده برای تشخیص ژست ارائه میدهد.
| نام کیت توسعه نرمافزار | PoseDetection | PoseDetectionAccurate |
|---|---|---|
| پیادهسازی | داراییهای آشکارساز پایه در زمان ساخت بهصورت ایستا به برنامهتان پیوند داده میشوند. | داراییهای مربوط به آشکارساز دقیق در زمان ساخت بهطور ایستا به برنامهتان پیوند داده میشود. |
| حجم برنامه | تا ۲۹٫۶ مگابایت | تا ۳۳٫۲ مگابایت |
| عملکرد | iPhone X: ~45FPS | iPhone X: ~29FPS |
امتحان کنید
- با برنامه نمونه کار کنید تا نمونهای از کاربرد این API را ببینید.
قبلاز شروع
پادهای ML Kit زیر را در Podfile خود اضافه کنید:
# If you want to use the base implementation: pod 'GoogleMLKit/PoseDetection', '8.0.0' # If you want to use the accurate implementation: pod 'GoogleMLKit/PoseDetectionAccurate', '8.0.0'پساز نصب یا بهروزرسانی podهای پروژهتان، پروژه Xcode را بااستفاده از
xcworkspaceآن باز کنید. «کیت یادگیری ماشین» در Xcode نسخه ۱۳.۲.۱ یا بالاتر پشتیبانی میشود.
۱. ایجاد نمونهای از PoseDetector
برای تشخیص دادن ژست در تصویر، ابتدا نمونهای از PoseDetector ایجاد کنید و
بهصورت اختیاری تنظیمات آشکارساز را مشخص کنید.
PoseDetector گزینه
حالت تشخیص
PoseDetector در دو حالت تشخیص کار میکند. حتماً موردی را انتخاب کنید که با مورد استفاده شما مطابقت دارد.
stream(پیشفرض)- تشخیصدهنده حالت ابتدا برجستهترین فرد را در تصویر تشخیص میدهد و سپس تشخیص حالت را اجرا میکند. در قابهای بعدی، مرحله تشخیص فرد انجام نخواهد شد، مگراینکه فرد مبهم شود یا دیگر با اطمینان بالا تشخیص داده نشود. تشخیصدهنده ژست تلاش میکند برجستهترین فرد را ردیابی کند و ژست او را در هر استنتاج برگرداند. این کار تأخیر را کاهش میدهد و تشخیص را روانتر میکند. وقتی میخواهید ژست را در جاریسازی ویدیو تشخیص دهید، از این حالت استفاده کنید.
singleImage- تشخیصدهنده حالت، فرد را تشخیص میدهد و سپس تشخیص حالت را اجرا میکند. مرحله تشخیص انسان برای هر تصویر اجرا میشود، بنابراین تأخیر بیشتر خواهد بود و ردیابی انسان وجود ندارد. از این حالت هنگام استفاده از تشخیص حالت در تصاویر ثابت یا جایی که ردیابی مطلوب نیست استفاده کنید.
گزینههای تشخیصدهنده حالت را مشخص کنید:
Swift
// Base pose detector with streaming, when depending on the PoseDetection SDK let options = PoseDetectorOptions() options.detectorMode = .stream // Accurate pose detector on static images, when depending on the // PoseDetectionAccurate SDK let options = AccuratePoseDetectorOptions() options.detectorMode = .singleImage
آبجکتیو-سی
// Base pose detector with streaming, when depending on the PoseDetection SDK MLKPoseDetectorOptions *options = [[MLKPoseDetectorOptions alloc] init]; options.detectorMode = MLKPoseDetectorModeStream; // Accurate pose detector on static images, when depending on the // PoseDetectionAccurate SDK MLKAccuratePoseDetectorOptions *options = [[MLKAccuratePoseDetectorOptions alloc] init]; options.detectorMode = MLKPoseDetectorModeSingleImage;
درنهایت، نمونهای از PoseDetector را دریافت کنید. گزینههایی را که مشخص کردهاید ارسال کنید:
Swift
let poseDetector = PoseDetector.poseDetector(options: options)
آبجکتیو-سی
MLKPoseDetector *poseDetector = [MLKPoseDetector poseDetectorWithOptions:options];
۲. آماده کردن تصویر ورودی
برای تشخیص ژستها، مراحل زیر را برای هر تصویر یا فریم ویدیو انجام دهید.
اگر حالت جاریسازی را فعال کردهاید، باید VisionImage شیء از
CMSampleBuffer ایجاد کنید.
بااستفاده از 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; } }
- ایجاد شیء
VisionImageبااستفاده از شیءCMSampleBufferو جهت: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];
۳. پردازش تصویر
VisionImage را به یکی از روشهای پردازش تصویر آشکارساز حالت ارسال کنید. میتوانید از روش ناهمگام process(image:) یا روش همگام results() استفاده کنید.
برای شناسایی همزمان اشیاء:
Swift
var results: [Pose] do { results = try poseDetector.results(in: image) } catch let error { print("Failed to detect pose with error: \(error.localizedDescription).") return } guard let detectedPoses = results, !detectedPoses.isEmpty else { print("Pose detector returned no results.") return } // Success. Get pose landmarks here.
آبجکتیو-سی
NSError *error; NSArray*poses = [poseDetector resultsInImage:image error:&error]; if (error != nil) { // Error. return; } if (poses.count == 0) { // No pose detected. return; } // Success. Get pose landmarks here.
برای شناسایی اشیاء بهصورت ناهمگام:
Swift
poseDetector.process(image) { detectedPoses, error in guard error == nil else { // Error. return } guard !detectedPoses.isEmpty else { // No pose detected. return } // Success. Get pose landmarks here. }
آبجکتیو-سی
[poseDetector processImage:image completion:^(NSArray* _Nullable poses, NSError * _Nullable error) { if (error != nil) { // Error. return; } if (poses.count == 0) { // No pose detected. return; } // Success. Get pose landmarks here. }];
۴. دریافت اطلاعات درباره حالت شناساییشده
اگر فردی در تصویر شناسایی شود، میانای برنامهسازی کاربردی تشخیص حالت یا آرایهای از اشیای Pose را به گرداننده تکمیل ارسال میکند یا آرایه را برمیگرداند، بسته به اینکه روش ناهمگام یا همگام را فراخوانی کرده باشید.
اگر فرد کاملاً داخل تصویر نباشد، مدل مختصات نقاط عطف گمشده را خارج از قاب اختصاص میدهد و به آنها مقادیر InFrameConfidence پایینی میدهد.
اگر هیچ فردی شناسایی نشود، آرایه خالی است.
Swift
for pose in detectedPoses { let leftAnkleLandmark = pose.landmark(ofType: .leftAnkle) if leftAnkleLandmark.inFrameLikelihood > 0.5 { let position = leftAnkleLandmark.position } }
آبجکتیو-سی
for (MLKPose *pose in detectedPoses) { MLKPoseLandmark *leftAnkleLandmark = [pose landmarkOfType:MLKPoseLandmarkTypeLeftAnkle]; if (leftAnkleLandmark.inFrameLikelihood > 0.5) { MLKVision3DPoint *position = leftAnkleLandmark.position; } }
نکتههایی برای بهبود عملکرد
کیفیت نتایج شما به کیفیت تصویر ورودی بستگی دارد:
- برای اینکه ML Kit بتواند حالت را بهدرستی تشخیص دهد، فرد موجود در تصویر باید با دادههای پیکسلی کافی نشان داده شود؛ برای بهترین عملکرد، سوژه باید حداقل ۲۵۶×۲۵۶ پیکسل باشد.
- اگر در برنامهای همزمان حالت را تشخیص میدهید، ممکن است بخواهید ابعاد کلی تصاویر ورودی را نیز درنظر بگیرید. تصاویر کوچکتر سریعتر پردازش میشوند، بنابراین برای کاهش تأخیر، تصاویر را با وضوح پایینتر ثبت کنید، اما الزامات وضوح بالا را درنظر داشته باشید و مطمئن شوید که سوژه تا حد امکان بخش بیشتری از تصویر را اشغال میکند.
- تمرکز ضعیف تصویر نیز میتواند بر دقت تأثیر بگذارد. اگر نتایج قابلقبولی دریافت نکردید، از کاربر بخواهید تصویر را دوباره بگیرد.
اگر میخواهید از تشخیص حالت در برنامه همزمان استفاده کنید، این دستورالعملها را دنبال کنید تا به بهترین نرخ فریم دست یابید:
- از کیت توسعه نرمافزار PoseDetection پایه و حالت تشخیص
streamاستفاده کنید. - تصاویر را با وضوح پایینتری بگیرید. بااینحال، الزامات ابعاد تصویر این API را نیز درنظر داشته باشید.
- برای پردازش فریمهای ویدیو، از
results(in:)API همگام آشکارساز استفاده کنید. این روش را از تابع captureOutput(_, didOutput:from:) مربوط به AVCaptureVideoDataOutputSampleBufferDelegate فراخوانی کنید تا نتایج را بهصورت همزمان از فریم ویدیو دادهشده دریافت کنید. alwaysDiscardsLateVideoFrames مربوط به AVCaptureVideoDataOutput را روی true (درست) نگه دارید تا تماسها با آشکارساز کنترل شود. اگر فریم ویدیو جدیدی درحین اجرای آشکارساز دردسترس قرار گیرد، حذف خواهد شد. - اگر از خروجی آشکارساز برای همپوشانی گرافیک روی تصویر ورودی استفاده میکنید، ابتدا نتیجه را از ML Kit دریافت کنید، سپس تصویر و همپوشانی را در یک مرحله رندر کنید. با انجام این کار، فقط یک بار برای هر فریم ورودی پردازششده به سطح نمایشگر رندر میکنید. برای دیدن نمونه، کلاسهای previewOverlayView و MLKDetectionOverlayView را در برنامه نمونه ویترین ببینید.
مراحل بعدی
- برای آشنایی با نحوه استفاده از نشانگرهای وضعیت برای طبقهبندی وضعیتها، به نکات طبقهبندی وضعیت مراجعه کنید.
- برای دیدن نمونهای از این API درحال استفاده، نمونه شروع سریع ML Kit را در GitHub ببینید.