ML Kit는 자세 감지에 최적화된 두 가지 SDK를 제공합니다.
SDK 이름 | PoseDetection | PoseDetectionAccurate |
---|---|---|
구현 | 기본 감지기의 애셋은 빌드 시 앱에 정적으로 연결됩니다. | 정확한 감지기를 위한 애셋은 빌드 시간에 앱에 정적으로 연결됩니다. |
앱 크기 | 최대 29.6MB | 최대 33.2MB |
성능 | iPhone X: ~45FPS | iPhone X: ~29FPS |
사용해 보기
- 샘플 앱을 사용하여 이 API의 사용 예를 참조하세요.
시작하기 전에
Podfile에 다음 ML Kit 포드를 포함합니다.
# If you want to use the base implementation: pod 'GoogleMLKit/PoseDetection', '3.2.0' # If you want to use the accurate implementation: pod 'GoogleMLKit/PoseDetectionAccurate', '3.2.0'
프로젝트의 포드를 설치하거나 업데이트한 후
xcworkspace
를 사용하여 Xcode 프로젝트를 엽니다. ML Kit는 Xcode 버전 13.2.1 이상에서 지원됩니다.
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
를 사용하는 경우 다음 단계를 따르세요.
UIImage
로VisionImage
객체를 만듭니다. 올바른.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. 감지된 포즈에 대한 정보 가져오기
이미지에서 사람이 감지되면 자세 감지 API가
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가 포즈를 정확하게 감지하려면 이미지 속 인물이 충분한 픽셀 데이터로 표시됩니다. 최적의 성능을 위해 제목을 최소 256x256픽셀이어야 합니다.
- 실시간 애플리케이션에서 포즈를 감지하는 경우 입력 이미지의 전체 크기입니다. 더 작은 이미지를 처리할 수 있음 지연 시간을 줄이기 위해 낮은 해상도에서 이미지를 캡처하지만 위의 해결 요구사항에 유의하고 주제가 이미지를 최대한 많이 넣어야 합니다
- 이미지 초점이 잘 맞지 않으면 정확도에 영향을 줄 수도 있습니다. 만족할 만한 결과를 얻지 못하면 사용자에게 이미지를 다시 캡처하도록 요청합니다.
실시간 애플리케이션에서 자세 감지를 사용하려는 경우 최상의 프레임 속도를 얻으려면 다음 안내를 따르세요.
- 기본 PoseDetection SDK 및
stream
감지 모드를 사용합니다. - 낮은 해상도에서 이미지를 캡처하는 것이 좋습니다. 그러나 이 API의 이미지 크기 요구사항도 유의해야 합니다.
- 동영상 프레임을 처리하려면 감지기의
results(in:)
동기 API를 사용하세요. AVCaptureVideoDataOutputSampleBufferDelegate의 captureOutput(_, didOutput:from:) 함수를 사용하여 지정된 동영상 프레임에서 동기식으로 결과를 가져옵니다. AVCaptureVideoDataOutput의 alwaysDiscardsLateVideoFrames를 true로 유지하여 감지기 호출을 제한합니다. 인식기가 실행 중일 때 새 동영상 프레임이 제공되는 경우 삭제됩니다. - 인식기 출력을 사용하여 입력 이미지에 그래픽을 오버레이하는 경우 먼저 ML Kit에서 결과를 가져온 후 이미지를 렌더링하고 단일 단계로 오버레이합니다. 이렇게 하면 처리된 입력 프레임마다 한 번만 디스플레이 표면에 렌더링됩니다. 자세한 내용은 previewOverlayView 및 MLKDetectionOverlayView 클래스를 확인해 보겠습니다.
다음 단계
- 랜드마크를 사용하여 포즈를 분류하는 방법을 알아보려면 포즈 분류 도움말을 참고하세요.
- 이 API의 사용 예시는 GitHub의 ML Kit 빠른 시작 샘플을 참조하세요.