توفّر حزمة تعلّم الآلة (ML Kit) حزمتَي SDK محسّنتَين لرصد الوضعيات.
| اسم حزمة SDK | PoseDetection | PoseDetectionAccurate |
|---|---|---|
| التنفيذ | يتم ربط مواد عرض أداة الرصد الأساسية بتطبيقك بشكل ثابت في مدّة التصميم. | يتم ربط مواد عرض أداة الرصد الدقيقة بتطبيقك بشكل ثابت في مدّة التصميم. |
| حجم التطبيق | يصل إلى 29.6 ميغابايت | يصل إلى 33.2 ميغابايت |
| الأداء | iPhone X: حوالي 45 لقطة في الثانية | iPhone X: حوالي 29 لقطة في الثانية |
للتجربة:
- يمكنكم تجربة التطبيق النموذجي للاطّلاع على مثال على استخدام واجهة برمجة التطبيقات هذه.
قبل البدء
أدرِج مجموعات الإعلانات المتسلسلة التالية من حزمة تعلّم الآلة (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) مع الإصدار 13.2.1 من Xcode أو الإصدارات الأحدث.
1- إنشاء مثيل من 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
Objective-C
// 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)
Objective-C
MLKPoseDetector *poseDetector = [MLKPoseDetector poseDetectorWithOptions:options];
2- تجهيز الصورة المُدخَلة
لرصد الوضعيات، اتّبِع الخطوات التالية لكل صورة أو إطار فيديو.
إذا فعّلت وضع البث، عليك إنشاء كائنات VisionImage من CMSampleBuffer.
أنشِئ كائن VisionImage باستخدام UIImage أو
CMSampleBuffer.
إذا كنت تستخدم 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;
إذا كنت تستخدم 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 } }
Objective-C
- (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)
Objective-C
MLKVisionImage *image = [[MLKVisionImage alloc] initWithBuffer:sampleBuffer]; image.orientation = [self imageOrientationFromDeviceOrientation:UIDevice.currentDevice.orientation cameraPosition:cameraPosition];
3- معالجة الصورة
مرِّر 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.
Objective-C
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. }
Objective-C
[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. }];
4- الحصول على معلومات عن الوضعية التي تم رصدها
إذا تم رصد شخص في الصورة، ستمرِّر واجهة برمجة التطبيقات لرصد الوضعيات إما مصفوفة من كائنات Pose إلى معالج الإكمال أو ستعرض المصفوفة، وذلك حسب ما إذا كنت قد استدعيت الطريقة غير المتزامنة أو المتزامنة.
إذا لم يكن الشخص داخل الصورة بالكامل، سيحدّد النموذج إحداثيات المعالم غير المرصودة خارج الإطار ويمنحها قيمًا منخفضة لـ InFrameConfidence.
إذا لم يتم رصد أي شخص، ستكون المصفوفة فارغة.
Swift
for pose in detectedPoses { let leftAnkleLandmark = pose.landmark(ofType: .leftAnkle) if leftAnkleLandmark.inFrameLikelihood > 0.5 { let position = leftAnkleLandmark.position } }
Objective-C
for (MLKPose *pose in detectedPoses) { MLKPoseLandmark *leftAnkleLandmark = [pose landmarkOfType:MLKPoseLandmarkTypeLeftAnkle]; if (leftAnkleLandmark.inFrameLikelihood > 0.5) { MLKVision3DPoint *position = leftAnkleLandmark.position; } }
نصائح لتحسين الأداء
تعتمد جودة النتائج على جودة الصورة المُدخَلة:
- لكي ترصد حزمة تعلّم الآلة (ML Kit) الوضعية بدقة، يجب أن يكون الشخص في الصورة ممثلاً ببيانات بكسل كافية. وللحصول على أفضل أداء، يجب أن يكون حجم العنصر 256 × 256 بكسل على الأقل.
- إذا كنت ترصد الوضعيات في تطبيق في الوقت الفعلي، قد تحتاج أيضًا إلى مراعاة الأبعاد العامة للصور المُدخَلة. يمكن معالجة الصور الأصغر حجمًا بشكل أسرع، لذا لتقليل وقت الاستجابة، التقط الصور بدقة أقل، ولكن ضَع في اعتبارك متطلبات الدقة المذكورة أعلاه وتأكَّد من أنّ العنصر يشغل أكبر مساحة ممكنة من الصورة.
- يمكن أن يؤثر عدم وضوح الصورة أيضًا في الدقة. إذا لم تحصل على نتائج مقبولة، اطلب من المستخدم إعادة التقاط الصورة.
إذا أردت استخدام ميزة رصد الوضعيات في تطبيق في الوقت الفعلي، اتّبِع هذه الإرشادات لتحقيق أفضل معدلات الإطارات:
- استخدِم حزمة PoseDetection SDK الأساسية ووضع الرصد
stream. - يمكنك التقاط الصور بدقة أقل. ومع ذلك، ضَع في اعتبارك أيضًا متطلبات أبعاد الصور في واجهة برمجة التطبيقات هذه.
- لمعالجة إطارات الفيديو، استخدِم واجهة برمجة التطبيقات المتزامنة
results(in:)الخاصة بأداة الرصد. استدعِ هذه الطريقة من الدالة AVCaptureVideoDataOutputSampleBufferDelegate's للحصول بشكل متزامن على نتائج من إطار الفيديو المُحدّد. اضبط AVCaptureVideoDataOutput على alwaysDiscardsLateVideoFrames بقيمة `true` للحدّ من عمليات استدعاء أداة الرصد. إذا أصبح إطار فيديو جديد متاحًا أثناء تشغيل أداة الرصد، سيتم تجاهله. - إذا كنت تستخدم ناتج أداة الرصد لتراكب الرسومات على الصورة المُدخَلة، احصل أولاً على النتيجة من حزمة تعلّم الآلة (ML Kit)، ثم اعرض الصورة والتراكب في خطوة واحدة. عند إجراء ذلك، ستعرض على سطح العرض مرة واحدة فقط لكل إطار إدخال تتم معالجته. يمكنك الاطّلاع على الفئتَين previewOverlayView و MLKDetectionOverlayView في نموذج تطبيق العرض التوضيحي للحصول على مثال.
الخطوات التالية
- للتعرّف على كيفية استخدام معالم الوضعيات لتصنيف الوضعيات، اطّلِع على مقالة نصائح بشأن تصنيف الوضعيات.
- يمكنك الاطّلاع على نموذج التشغيل السريع لحزمة تعلّم الآلة (ML Kit) على GitHub للحصول على مثال على استخدام واجهة برمجة التطبيقات هذه.