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'پساز نصب یا بهروزرسانی پادهای پروژهتان، پروژه Xcode را بااستفاده از
xcworkspaceآن باز کنید. ML Kit در 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 استفاده میکنید، این مراحل را دنبال کنید:
- با
UIImage، شیءVisionImageایجاد کنید. حتماً.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];
۳. پردازش تصویر
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. }];
۴. دریافت اطلاعات درباره ژست شناساییشده
اگر فردی در تصویر تشخیص داده شود، API تشخیص ژست یا آرایهای از 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:)آشکارساز استفاده کنید. این روش را از تابع AVCaptureVideoDataOutputSampleBufferDelegate captureOutput(_, didOutput:from:) فراخوانی کنید تا نتایج را بهصورت همزمان از قاب ویدیو دادهشده دریافت کنید. AVCaptureVideoDataOutput را با alwaysDiscardsLateVideoFrames روی درست تنظیم کنید تا تماسهای برقرارشده با آشکارساز را محدود کنید. اگر قاب ویدیو جدیدی درحین اجرای آشکارساز دردسترس قرار گیرد، حذف خواهد شد. - اگر از برونداد آشکارساز برای رونهادن گرافیک روی تصویر ورودی استفاده میکنید، ابتدا نتیجه را از ML Kit دریافت کنید، سپس تصویر و رونهاد را در یک مرحله پردازش کنید. با انجام این کار، برای هر قاب ورودی پردازششده، فقط یکبار به سطح نمایشگر رندر میکنید. برای دیدن نمونه، کلاسهای previewOverlayView و MLKDetectionOverlayView را در برنامه نمونه ویترین مشاهده کنید.
مراحل بعدی
- برای آشنایی با نحوه استفاده از نقاط مرجع ژست برای طبقهبندی ژستها، نکتههایی درباره طبقهبندی ژست را ببینید.
- برای مشاهده نمونهای از این API درحال استفاده، نمونه شروع سریع ML Kit را در GitHub ببینید.