ML Kit udostępnia 2 zoptymalizowane pakiety SDK do wykrywania postaw.
Nazwa pakietu SDK | PoseDetection | PoseDetectionAccurate |
---|---|---|
Implementacja | Zasoby dla podstawowego modułu wykrywającego są statycznie powiązane z aplikacją w momencie kompilacji. | Komponenty dokładnego detektora są statycznie powiązane z aplikacją w momencie kompilacji. |
Rozmiar aplikacji | Do 29,6 MB | Do 33,2 MB |
Wyniki | iPhone X: ok. 45 FPS | iPhone X: około 29 FPS |
Wypróbuj
- Aby zobaczyć przykład użycia tego interfejsu API, wypróbuj przykładową aplikację.
Zanim zaczniesz
Dodaj do pliku Podfile te pody ML Kit:
# If you want to use the base implementation: pod 'GoogleMLKit/PoseDetection', '7.0.0' # If you want to use the accurate implementation: pod 'GoogleMLKit/PoseDetectionAccurate', '7.0.0'
Po zainstalowaniu lub zaktualizowaniu modułów projektu otwórz projekt Xcode, używając jego
xcworkspace
. ML Kit jest obsługiwany w Xcode w wersji 13.2.1 lub nowszej.
1. Utwórz instancję PoseDetector
Aby wykryć pozę na zdjęciu, najpierw utwórz instancję funkcji PoseDetector
i opcjonalnie określ ustawienia detektora.
Opcje: PoseDetector
Tryb wykrywania
Urządzenie PoseDetector
działa w 2 trybach wykrywania. Pamiętaj, aby wybrać model, który odpowiada Twoim potrzebom.
stream
(domyślnie)- Detektor pozy najpierw wykryje najbardziej widoczną osobę na zdjęciu, a potem przeprowadzi wykrywanie pozy. W kolejnych klatkach krok wykrywania osób nie będzie wykonywany, chyba że osoba zostanie zasłonięta lub nie będzie już wykrywana z wysoką pewnością. Detektor postawy będzie próbować śledzić najbardziej widoczną osobę i zwracać jej postawę w każdej prognozie. Pozwala to zmniejszyć opóźnienia i usprawnić wykrywanie. Użyj tego trybu, gdy chcesz wykrywać pozę w strumieniu wideo.
singleImage
- Wykrywacz pozy wykryje osobę, a następnie przeprowadzi wykrywanie pozy. Etap wykrywania osób będzie wykonywany w przypadku każdego obrazu, więc opóźnienie będzie większe, a śledzenie osób nie będzie możliwe. Używaj tego trybu, gdy używasz wykrywania pozycji ciała na zdjęciach statycznych lub gdy śledzenie nie jest potrzebne.
Określ opcje detektora pozy:
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;
Na koniec pobierz instancję PoseDetector
. Przekaż określone opcje:
Swift
let poseDetector = PoseDetector.poseDetector(options: options)
Objective-C
MLKPoseDetector *poseDetector = [MLKPoseDetector poseDetectorWithOptions:options];
2. Przygotuj obraz wejściowy
Aby wykryć pozy, wykonaj te czynności w przypadku każdego obrazu lub każdego kadru filmu.
Jeśli masz włączony tryb strumieniowania, musisz utworzyć obiekty VisionImage
z CMSampleBuffer
.
Utwórz obiekt VisionImage
za pomocą obiektu UIImage
lub CMSampleBuffer
.
Jeśli używasz UIImage
, wykonaj te czynności:
- Utwórz obiekt
VisionImage
za pomocą funkcjiUIImage
. Pamiętaj, aby podać prawidłowy adres.orientation
.Swift
let image = VisionImage(image: UIImage) visionImage.orientation = image.imageOrientation
Objective-C
MLKVisionImage *visionImage = [[MLKVisionImage alloc] initWithImage:image]; visionImage.orientation = image.imageOrientation;
Jeśli używasz CMSampleBuffer
, wykonaj te czynności:
-
Określ orientację danych obrazu zawartych w elemencie
CMSampleBuffer
.Aby uzyskać orientację obrazu:
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; } }
- Utwórz obiekt
VisionImage
, używając obiektuCMSampleBuffer
i jego orientacji: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. Przetwarzanie obrazu
Przekaż VisionImage
do jednej z metod przetwarzania obrazu w detektorze pozy. Możesz użyć asynchronicznej metody process(image:)
lub synchronicznej metody results()
.
Aby wykrywać obiekty synchronicznie:
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.
Aby wykrywać obiekty asynchronicznie:
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. Uzyskiwanie informacji o wykryciu pozy
Jeśli na obrazie zostanie wykryta osoba, interfejs API wykrywania pozycji ciała przekaże tablicę obiektów Pose
do metody obsługi zakończenia lub zwróci tablicę, w zależności od tego, czy wywołano metodę asynchroniczną czy synchroniczną.
Jeśli osoba nie była w pełni widoczna na zdjęciu, model przypisuje brakujące współrzędne punktów orientacyjnych poza kadrem i przypisuje im niskie wartości InFrameConfidence.
Jeśli nie wykryto żadnej osoby, tablica jest pusta.
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; } }
Wskazówki dotyczące zwiększania skuteczności
Jakość wyników zależy od jakości obrazu wejściowego:
- Aby ML Kit mógł dokładnie wykrywać pozę, osoba na zdjęciu powinna być reprezentowana przez wystarczającą ilość danych pikseli. Aby uzyskać najlepsze wyniki, obiekt powinien mieć co najmniej 256 × 256 pikseli.
- Jeśli wykrywanie pozy odbywa się w aplikacji w czasie rzeczywistym, warto też wziąć pod uwagę ogólne wymiary obrazów wejściowych. Mniejsze obrazy można przetwarzać szybciej, więc aby zmniejszyć opóźnienie, rób zdjęcia w niższej rozdzielczości, pamiętając o wymienionych powyżej wymaganiach dotyczących rozdzielczości i upewnij się, że fotografowany obiekt zajmuje jak największą część obrazu.
- Na dokładność może też wpływać niewłaściwe ustawienie ostrości. Jeśli nie uzyskasz zadowalających wyników, poproś użytkownika o ponowne zrobienie zdjęcia.
Jeśli chcesz używać wykrywania pozy w aplikacji działającej w czasie rzeczywistym, postępuj zgodnie z tymi wskazówkami, aby uzyskać najlepszą liczbę klatek na sekundę:
- Użyj podstawowego pakietu SDK wykrywania pozycji i trybu wykrywania
stream
. - Rozważ robienie zdjęć w niższej rozdzielczości. Pamiętaj jednak o wymaganiach dotyczących wymiarów obrazu w tym interfejsie API.
- Do przetwarzania klatek wideo użyj synchronicznego interfejsu API
results(in:)
do wykrywania. Wywołaj tę metodę z poziomu interfejsu AVCaptureVideoDataOutputSampleBufferDelegate, aby synchronicznie uzyskać wyniki z danego kadru wideo.captureOutput(_, didOutput:from:) Aby ograniczyć wywołania do detektora, ustaw parametr AVCaptureVideoDataOutput na alwaysDiscardsLateVideoFrames. Jeśli podczas działania detektora pojawi się nowa klatka wideo, zostanie ona odrzucona. - Jeśli używasz danych wyjściowych z detektora do nakładania grafiki na obraz wejściowy, najpierw uzyskaj wynik z ML Kit, a potem wyrenderuj obraz i nakładkę w jednym kroku. Dzięki temu renderowanie na powierzchni wyświetlacza odbywa się tylko raz dla każdego przetworzonego kadru wejściowego. Przykładem są klasy previewOverlayView i MLKDetectionOverlayView w przykładowej aplikacji pokazowej.
Dalsze kroki
- Aby dowiedzieć się, jak używać punktów orientacyjnych pozy do klasyfikowania poz, przeczytaj artykuł Wskazówki dotyczące klasyfikacji poz.
- Przykład użycia tego interfejsu API znajdziesz na GitHubie w przykładowym pliku źródłowym ML Kit.