ML Kit udostępnia 2 zoptymalizowane pakiety SDK do wykrywania pozycji.
Nazwa pakietu SDK | PoseDetection | PoseDetectionAccurate |
---|---|---|
Implementacja | Zasoby podstawowego wzorca do wykrywania treści są statycznie połączone z aplikacją w czasie kompilacji. | Zasoby zapewniające dokładny detektor są statycznie połączone z aplikacją w czasie kompilacji. |
Rozmiar aplikacji | Do 29,6 MB | Do 33,2 MB |
Występy | iPhone X: ~45 kl./s | iPhone X: ~29 kl./s |
Wypróbuj
- Przetestuj przykładową aplikację, aby zobaczyć przykład użycia tego interfejsu API.
Zanim zaczniesz
W pliku Podfile umieść te pody 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'
Po zainstalowaniu lub zaktualizowaniu podów projektu otwórz projekt Xcode za pomocą
xcworkspace
. ML Kit jest obsługiwany w Xcode w wersji 13.2.1 lub nowszej.
1. Utwórz instancję PoseDetector
Aby wykryć pozę na obrazie, najpierw utwórz instancję PoseDetector
i opcjonalnie określ ustawienia wzorca do wykrywania treści.
Opcje: PoseDetector
Tryb wykrywania
PoseDetector
działa w 2 trybach wykrywania. Wybierz taki, który pasuje
do Twojego przypadku użycia.
stream
(domyślnie)- Wykrywanie pozycji najpierw wykryje najwyższą osobę na zdjęciu, a potem uruchomi wykrywanie pozycji. W kolejnych klatkach etap wykrywania osoby nie zostanie przeprowadzony, chyba że osoba ta pojawi się w cieniu lub nie będzie już wykryta z dużym prawdopodobieństwem. Wykrywanie pozycji spróbuje śledzić najbardziej widoczną osobę i przy każdym wnioskowaniu określać pozycję. Pozwala to skrócić czas oczekiwania i płynnie wykrywać wykrywanie. Użyj tego trybu, gdy chcesz wykryć pozę w strumieniu wideo.
singleImage
- Wykrywanie pozycji wykryje osobę, a następnie uruchomi wykrywanie pozycji. Etap wykrywania osób będzie przeprowadzany dla każdego obrazu, więc opóźnienia będą większe i nie będzie funkcji śledzenia osób. Użyj tego trybu, gdy wykrywasz pozycję na obrazach statycznych lub gdy śledzenie nie jest pożądane.
Określ opcje wykrywania pozycji:
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 wystąpienie PoseDetector
. Przekaż określone opcje:
Swift
let poseDetector = PoseDetector.poseDetector(options: options)
Objective-C
MLKPoseDetector *poseDetector = [MLKPoseDetector poseDetectorWithOptions:options];
2. Przygotowywanie obrazu wejściowego
Aby wykryć pozycje, wykonaj te czynności w przypadku każdego obrazu lub klatki filmu.
Jeśli masz włączony tryb strumieniowania, musisz utworzyć obiekty VisionImage
z CMSampleBuffer
.
Utwórz obiekt VisionImage
za pomocą UIImage
lub CMSampleBuffer
.
Jeśli używasz konta UIImage
, wykonaj te czynności:
- Utwórz obiekt
VisionImage
zUIImage
. Pamiętaj, aby podać prawidłowy atrybut.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 konta CMSampleBuffer
, wykonaj te czynności:
-
Określ orientację danych obrazu zawartych w pliku
CMSampleBuffer
.Aby określić orientację zdjęcia:
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 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 stosowanych przez detektor pozycji. Możesz użyć asynchronicznej metody process(image:)
lub synchronicznej 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 asynchronicznie wykrywać obiekty:
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. Uzyskaj informacje o wykrytej pozycji
Jeśli na obrazie zostanie wykryta osoba, interfejs API wykrywania pozycji przekazuje tablicę obiektów Pose
do modułu obsługi ukończenia lub zwraca tablicę w zależności od tego, czy wywołano metodę asynchroniczną czy synchroniczną.
Jeśli dana osoba nie była w pełni widoczna na zdjęciu, model przypisuje brakujące współrzędne punktów orientacyjnych poza ramką i nadaje 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 poprawy skuteczności
Jakość wyników zależy od jakości obrazu wejściowego:
- Aby narzędzie ML Kit mogło dokładnie wykryć pozycję osoby, osoba na obrazie powinna być reprezentowana przez wystarczającą ilość danych pikseli. Najlepsze wyniki uzyskasz, jeśli osoba zdjęcia będzie mieć rozmiar co najmniej 256 x 256 pikseli.
- Jeśli wykryjesz pozycję w aplikacji przesyłających dane w czasie rzeczywistym, możesz też wziąć pod uwagę ogólne wymiary obrazów wejściowych. Mniejsze obrazy mogą być przetwarzane szybciej. Aby zmniejszyć opóźnienie, zrób zdjęcia w niższej rozdzielczości, pamiętaj przy tym o powyższych wymaganiach dotyczących rozdzielczości i upewnij się, że obiekt zajmuje jak największą część obrazu.
- Słaba ostrość obrazu może również wpływać na dokładność. Jeśli nie uzyskasz zadowalających wyników, poproś użytkownika o ponowne zrobienie zdjęcia.
Jeśli chcesz używać wykrywania pozycji w aplikacji korzystającej z danych w czasie rzeczywistym, postępuj zgodnie z tymi wskazówkami, aby uzyskać najlepszą liczbę klatek na sekundę:
- Użyj podstawowego pakietu PoseDetection SDK i trybu wykrywania
stream
. - Rozważ robienie zdjęć w niższej rozdzielczości. Pamiętaj jednak o wymaganiach dotyczących wymiarów obrazów w tym interfejsie API.
- Do przetwarzania klatek wideo użyj synchronicznego interfejsu API
results(in:)
wzorca. Wywołaj tę metodę z funkcji AVCaptureVideoDataOutputSampleBufferDelegate w funkcji captureOutput(_, didOutput:from:), aby synchronicznie pobierać wyniki z danej klatki wideo. Aby ograniczać wywołania do wzorca, ustaw opcję AVCaptureVideoDataOutput na wartość alwaysDiscardsLateVideoFrames na wartość true (prawda). Jeśli w działaniu czujnika pojawi się nowa klatka wideo, zostanie usunięta. - Jeśli używasz danych wyjściowych detektora do nakładania grafiki na obraz wejściowy, najpierw pobierz wynik z ML Kit, a następnie w jednym kroku wyrenderuj obraz i nakładkę. Dzięki temu renderujesz na wyświetlaczu tylko raz dla każdej przetworzonej ramki wejściowej. Przykład znajdziesz w klasach previewOverlayView i MLKDetectionOverlayView w przykładowej aplikacji z prezentacją.
Dalsze kroki
- Aby dowiedzieć się, jak używać punktów orientacyjnych do klasyfikowania pozycji, przeczytaj wskazówki dotyczące klasyfikacji ułożeń.
- Przykład użycia tego interfejsu API znajdziesz w krótkim wprowadzeniu do ML Kit na GitHubie.