Dzięki interfejsowi ML Kit Pose Detection API możesz wyciągać wnioski ułożenia pozycji przez sprawdzenie względnych pozycji różnych części ciała. Ta strona przedstawi kilka przykładów.
Klasyfikacja pozycji i liczenie powtórzeń za pomocą algorytmu k-NN
Jednym z najczęstszych zastosowań wykrywania pozycji jest śledzenie aktywności. Tworzenie klasyfikatora pozycji, który rozpoznaje określone pozycje i liczebniki sprawności fizycznej i powtórzenia to nie lada wyzwanie dla programistów.
W tej sekcji opisujemy, jak utworzyć niestandardową pozę klasyfikatora za pomocą MediaPipe Colab, zademonstrować działający klasyfikator w naszej przykładowej aplikacji ML Kit.
Jeśli nie znasz Google Colaboratory, zapoznaj się z przewodnika.
Do rozpoznawania póz używamy algorytmu k-najbliższych sąsiadów (k-NN), ponieważ jest on prosty jest łatwa w użyciu. Algorytm określa klasę obiektu na podstawie jak najbliższe próbki w zbiorze treningowym.
Aby utworzyć i wytrenować moduł rozpoznawania, wykonaj te czynności:
1. Zbieranie próbek obrazów
Zebraliśmy z różnych źródeł próbki obrazów ćwiczeń docelowych. Śr wybrać po kilkaset zdjęć dla każdego ćwiczenia, np. "w górę", i „w dół” pozycje do pompek. Ważne jest, aby zbierać próbki obejmujące różne aparaty kątów, warunków środowiskowych, kształtów ciała i wahań ćwiczeń.
![](https://developers-dot-devsite-v2-prod.appspot.com/static/ml-kit/images/vision/pose-detection/terminal_pose.png?authuser=4&hl=pl)
2. Uruchom wykrywanie pozycji na przykładowych obrazach
W ten sposób powstanie zestaw punktów orientacyjnych pozycji do trenowania. Nie jesteśmy zainteresowanym samym wykrywaniem pozycji, ponieważ będziemy trenować dla swojego modelu.
Wybrany algorytm k-NN do niestandardowej klasyfikacji pozycji wymaga reprezentacja wektorów cech dla każdej próby i wskaźnika do obliczenia odległość między dwoma wektorami, aby znaleźć wartość docelową najbliższą danej pozycji. Oznacza to, że musimy przekonwertować uzyskane punkty orientacyjne pozycji.
Aby przekonwertować punkty orientacyjne ułożenia na wektor cech, korzystamy z odległości w parach między wstępnie zdefiniowanymi listami stawów, np. odległość między nadgarstkiem ramiona, kostki i biodra, a także lewe i prawe nadgarstki. Skala obrazów mogą się wahać, znormalizowaliśmy pozycje, aby miały taki sam rozmiar tułowia i pionową sylwetkę przed przekształceniem punktów orientacyjnych.
3. Wytrenuj model i zlicz powtórzenia
Użyliśmy MediaPipe Colab, by uzyskać dostęp do kodu klasyfikatora. i wytrenować model.
Do liczenia powtórzeń użyliśmy innego algorytmu Colab do monitorowania prawdopodobieństwa, w pozycji docelowej. Na przykład:
- Gdy prawdopodobieństwo spadku wartości klasa pozycji przekracza określony próg dla za pierwszym razem algorytm zaznacza, że słowo „w dół” klasa pozycji została opublikowana.
- Gdy prawdopodobieństwo spada poniżej progu, algorytm oznacza, że „w dół” klasa pozycji została zamknięta i zwiększa licznik.
![](https://developers-dot-devsite-v2-prod.appspot.com/static/ml-kit/images/vision/pose-detection/pose_classification.gif?authuser=4&hl=pl)
4. Integracja z aplikacją ML Kit
Powyższy kod Colab generuje plik CSV, w którym możesz podać całą ustaloną pozycję przykłady. W tej sekcji dowiesz się, jak zintegrować plik CSV z narzędziem Aplikacja ML Kit na Androida z niestandardową klasyfikacją pozycji w czasie rzeczywistym.
Wypróbuj klasyfikację pozycji z przykładami dostępnymi w aplikacji z krótkim wprowadzeniem
- Pobierz projekt aplikacji ML Kit na Androida z krótkim wprowadzeniem z GitHuba i upewnij się, że kompiluje i działa dobrze.
- Otwórz aplikację
LivePreviewActivity
i włącz wykrywanie pozycjiRun classification
na karcie Ustawienia stronę. Teraz umiesz klasyfikować pompki i przysiady.
Dodaj własny plik CSV
- Dodaj plik CSV do folderu zasobów aplikacji.
- W klastrze PoseClassifierProcessor
zaktualizuj zmienne
POSE_SAMPLES_FILE
iPOSE_CLASSES
, tak by pasowały do Plik CSV i przykłady pozycji. - Skompilować i uruchomić aplikację.
Pamiętaj, że klasyfikacja może nie działać dobrze, jeśli nie ma wystarczającej liczby próbek. Ogólnie potrzebujesz około 100 próbek na każdą klasę pozycji.
Aby dowiedzieć się więcej i samodzielnie wypróbować tę funkcję, zajrzyj do MediaPipe Colab i Przewodnik po klasyfikacji MediaPipe.
Rozpoznawanie prostych gestów przez obliczanie odległości do punktu orientacyjnego
Gdy co najmniej dwa punkty orientacyjne znajdują się blisko siebie, można ich używać do: rozpoznawania gestów. Na przykład gdy punkt orientacyjny dla co najmniej jednego palca na zdjęciu jest blisko punktu orientacyjnego nosa, można więc wywnioskować, że użytkownik najbardziej dotyka twarzy.
![](https://developers-dot-devsite-v2-prod.appspot.com/static/ml-kit/images/vision/pose-detection/touching_face.gif?authuser=4&hl=pl)
Rozpoznawanie pozycji jogi na podstawie heurystyki kąta
Pozycję jogi można rozpoznać po pomiarze kątów różnych stawów. Dla: Rysunek 2 poniżej przedstawia pozycję jogi Wojownika II. Przybliżone kąty identyfikujące tę pozę są zapisane w języku:
![](https://developers-dot-devsite-v2-prod.appspot.com/static/ml-kit/images/vision/pose-detection/warrier2_sketch.png?authuser=4&hl=pl)
Ta pozycja może zostać opisana w ten sposób: kąty części:
- Kąt pod kątem obu ramion
- 180 stopni na obu łokciach
- Kąt pod kątem 90 stopni z przedniej nogi i talii
- Kąt pod kątem 180 stopni w tylnej części kolana
- Kąt pod kątem 135 stopni w talii
Możesz użyć punktów orientacyjnych pozycji, aby obliczyć te kąty. Na przykład kąt przy prawej przedniej nodze, a w pasie to kąt między linią od prawej od ramienia do prawego biodra i linii od prawego biodra do prawego kolana.
Po obliczeniu wszystkich kątów potrzebnych do określenia pozycji możesz sprawdzić aby sprawdzić, czy uda Ci się znaleźć dopasowanie. W takim przypadku rozpoznasz pozy.
Fragment kodu poniżej pokazuje, jak używać współrzędnych X i Y do oblicz kąt między dwiema częściami ciała. Takie podejście do klasyfikacji ma pewne ograniczenia. Po zaznaczeniu tylko wartości X i Y obliczone kąty będą się różnić zgodnie z kątem między obiektem a kamerą. Otrzymasz aby uzyskać najlepsze wyniki, wystarczająco proste. Możesz też spróbuj rozszerzyć ten algorytm, korzystając z Współrzędna Z i sprawdzić, czy sprawdza się lepiej w Twoim przypadku użycia.
Obliczanie kątów punktu orientacyjnego na Androidzie
Poniższa metoda oblicza kąt między dowolnymi 3 dowolnych punkty orientacyjne. Daje on pewność, że zwrócony kąt znajduje się między od 0 do 180 stopni.
Kotlin
fun getAngle(firstPoint: PoseLandmark, midPoint: PoseLandmark, lastPoint: PoseLandmark): Double { var result = Math.toDegrees(atan2(lastPoint.getPosition().y - midPoint.getPosition().y, lastPoint.getPosition().x - midPoint.getPosition().x) - atan2(firstPoint.getPosition().y - midPoint.getPosition().y, firstPoint.getPosition().x - midPoint.getPosition().x)) result = Math.abs(result) // Angle should never be negative if (result > 180) { result = 360.0 - result // Always get the acute representation of the angle } return result }
Java
static double getAngle(PoseLandmark firstPoint, PoseLandmark midPoint, PoseLandmark lastPoint) { double result = Math.toDegrees( atan2(lastPoint.getPosition().y - midPoint.getPosition().y, lastPoint.getPosition().x - midPoint.getPosition().x) - atan2(firstPoint.getPosition().y - midPoint.getPosition().y, firstPoint.getPosition().x - midPoint.getPosition().x)); result = Math.abs(result); // Angle should never be negative if (result > 180) { result = (360.0 - result); // Always get the acute representation of the angle } return result; }
Oto jak obliczyć kąt przy prawej biodrze:
Kotlin
val rightHipAngle = getAngle( pose.getPoseLandmark(PoseLandmark.Type.RIGHT_SHOULDER), pose.getPoseLandmark(PoseLandmark.Type.RIGHT_HIP), pose.getPoseLandmark(PoseLandmark.Type.RIGHT_KNEE))
Java
double rightHipAngle = getAngle( pose.getPoseLandmark(PoseLandmark.Type.RIGHT_SHOULDER), pose.getPoseLandmark(PoseLandmark.Type.RIGHT_HIP), pose.getPoseLandmark(PoseLandmark.Type.RIGHT_KNEE));
Obliczanie kątów punktu orientacyjnego na urządzeniach z iOS
Poniższa metoda oblicza kąt między dowolnymi 3 dowolnych punkty orientacyjne. Daje on pewność, że zwrócony kąt znajduje się między od 0 do 180 stopni.
Swift
func angle( firstLandmark: PoseLandmark, midLandmark: PoseLandmark, lastLandmark: PoseLandmark ) -> CGFloat { let radians: CGFloat = atan2(lastLandmark.position.y - midLandmark.position.y, lastLandmark.position.x - midLandmark.position.x) - atan2(firstLandmark.position.y - midLandmark.position.y, firstLandmark.position.x - midLandmark.position.x) var degrees = radians * 180.0 / .pi degrees = abs(degrees) // Angle should never be negative if degrees > 180.0 { degrees = 360.0 - degrees // Always get the acute representation of the angle } return degrees }
Objective-C
(CGFloat)angleFromFirstLandmark:(MLKPoseLandmark *)firstLandmark midLandmark:(MLKPoseLandmark *)midLandmark lastLandmark:(MLKPoseLandmark *)lastLandmark { CGFloat radians = atan2(lastLandmark.position.y - midLandmark.position.y, lastLandmark.position.x - midLandmark.position.x) - atan2(firstLandmark.position.y - midLandmark.position.y, firstLandmark.position.x - midLandmark.position.x); CGFloat degrees = radians * 180.0 / M_PI; degrees = fabs(degrees); // Angle should never be negative if (degrees > 180.0) { degrees = 360.0 - degrees; // Always get the acute representation of the angle } return degrees; }
Oto jak obliczyć kąt przy prawej biodrze:
Swift
let rightHipAngle = angle( firstLandmark: pose.landmark(ofType: .rightShoulder), midLandmark: pose.landmark(ofType: .rightHip), lastLandmark: pose.landmark(ofType: .rightKnee))
Objective-C
CGFloat rightHipAngle = [self angleFromFirstLandmark:[pose landmarkOfType:MLKPoseLandmarkTypeRightShoulder] midLandmark:[pose landmarkOfType:MLKPoseLandmarkTypeRightHip] lastLandmark:[pose landmarkOfType:MLKPoseLandmarkTypeRightKnee]];