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 momencie kompilacji. | Zasoby dokładnego detektora są statycznie połączone z aplikacją w momencie kompilacji. |
Rozmiar aplikacji | Do 29,6 MB | Maks.33,2 MB |
Wyniki | iPhone X: ok. 45 kl./s | iPhone X: ok. 29 kl./s |
Wypróbuj
- Wypróbuj przykładową aplikację, aby: zobaczysz 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ą zasobu
xcworkspace
. ML Kit jest obsługiwany w Xcode w wersji 13.2.1 lub nowszej.
1. Tworzenie instancji maszyny wirtualnej PoseDetector
Aby wykryć pozę na zdjęciu, najpierw utwórz instancję PoseDetector
i
opcjonalnie określić ustawienia wzorca do wykrywania treści.
Opcje: PoseDetector
Tryb wykrywania
PoseDetector
działa w 2 trybach wykrywania. Wybierz ten, który pasuje
do Twojego przypadku użycia.
stream
(domyślnie)- Wykrywanie pozycji najpierw wykryje ważnej osoby na zdjęciu, a następnie uruchomić wykrywanie pozycji. W kolejnych klatkach etap wykrywania osoby nie zostanie przeprowadzony, zasłonięty lub nie jest już wykrywany z wysokim poziomem ufności. Wykrywanie pozycji będzie starać się wyśledzić najbardziej widoczną osobę i użyć jej ubrań wnioskowania. Pozwala to zmniejszyć czas oczekiwania i płynnie wykrywanie. Używaj tego trybu, gdy: chcą wykrywać pozy w strumieniu wideo.
singleImage
- Czujnik pozycji wykryje osobę i wykona pozycję wykrywaniem zagrożeń. Krok wykrywania osoby będzie wykonywany dla każdego obrazu, więc opóźnienie będzie będzie wyższy i nie będzie można śledzić osób. Używaj tego trybu podczas używania pozycji obrazów statycznych lub miejsc, w których ś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 instancję PoseDetector
. Prześlij określone opcje:
Swift
let poseDetector = PoseDetector.poseDetector(options: options)
Objective-C
MLKPoseDetector *poseDetector = [MLKPoseDetector poseDetectorWithOptions:options];
2. Przygotowywanie obrazu wejściowego
Aby wykrywać pozycje, wykonaj te czynności w przypadku każdego zdjęcia lub każdej 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 UIImage
, wykonaj te czynności:
- Utwórz obiekt
VisionImage
za pomocąUIImage
. Pamiętaj, by określić prawidłowy.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 zdjęć zawartych w pliku
CMSampleBuffer
Aby sprawdzić 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
za pomocąCMSampleBuffer
obiekt i orientacja: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 zdjęcia
Przekaż VisionImage
do jednej z metod przetwarzania obrazu przez detektor pozycji. Możesz używać asynchronicznej metody process(image:)
lub synchronicznej results()
.
Aby synchronicznie wykrywać obiekty:
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 ktoś wykryje osobę na zdjęciu, interfejs API do wykrywania pozycji przekazuje
tablica obiektów Pose
do modułu obsługi uzupełniania lub zwraca tablicę,
w zależności od tego, czy została wywołana metoda asynchroniczna czy synchroniczna.
Jeśli dana osoba nie była na zdjęciu w całości, model przypisuje brakujące współrzędne punktów końcowych poza ramką, powodując 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ść obrazu zależy od jakości obrazu wejściowego:
- Aby ML Kit mógł precyzyjnie wykryć pozę, osoba na zdjęciu powinna być jest reprezentowana przez wystarczającą ilość danych pikseli; aby uzyskać najlepszą skuteczność, obiekt powinien mieć rozmiar co najmniej 256 x 256 pikseli.
- Jeśli wykryjesz pozę w aplikacji działającej w czasie rzeczywistym, ogólne wymiary obrazów wejściowych. Mniejsze obrazy mogą być przetwarzane szybciej. Aby zmniejszyć opóźnienie, można robić zdjęcia w niższej rozdzielczości, pamiętaj o powyższych wymaganiach dotyczących rozwiązania problemu i upewnij się, że obiekt zajmuje jak najwięcej elementów.
- Słaba ostrość obrazu również może mieć wpływ na dokładność. Jeśli nie uzyskasz akceptowalnych wyników, poproś użytkownika o ponowne zrobienie zdjęcia.
Jeśli chcesz korzystać z wykrywania pozycji w aplikacjach w czasie rzeczywistym, postępuj zgodnie z tymi wskazówkami, aby uzyskać najlepszą liczbę klatek na sekundę:
- Użyj podstawowego pakietu SDK PoseDetection i trybu wykrywania
stream
. - Rozważ robienie zdjęć w niższej rozdzielczości. Pamiętaj jednak o wymaganiach tego interfejsu API dotyczących wymiarów zdjęć.
- Do przetwarzania klatek wideo używaj synchronicznego interfejsu API
results(in:)
detektora. Wywołaj tę metodę z klasy AVCaptureVideoDataOutputSampleBufferDelegate Funkcja captureOutput(_, didOutput:from:) służy do synchronicznego pobierania wyników dotyczących danej klatki filmu. Aby ograniczyć wywołania do detektora, w atrybucie AVCaptureVideoDataOutput ustaw wartość alwaysDiscardsLateVideoFrames na wartość true (prawda). Jeśli dostępna będzie nowa klatka wideo, gdy działa detektor, 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 wyrenderuj obraz i nakładkę w jednym kroku. Dzięki temu renderowanie na powierzchni wyświetlania będzie odbywać się tylko raz na każdą przetworzoną klatkę wejściową. Zobacz previewOverlayView i MLKDetectionOverlayView w aplikacji z funkcją prezentacji.
Dalsze kroki
- Aby dowiedzieć się, jak używać punktów orientacyjnych do klasyfikowania póz, przeczytaj Wskazówki dotyczące klasyfikacji pozycji.
- Przykład użycia tego interfejsu API znajdziesz w krótkim wprowadzeniu do korzystania z ML Kit na GitHubie.