Dzięki interfejsowi ML Kit Pose Detection API możesz uzyskać istotne interpretacje pozy, sprawdzając względne pozycje różnych części ciała. Na tej stronie znajdziesz kilka przykładów.
Klasyfikacja pozy i zliczanie 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 zbudowaliśmy niestandardowy klasyfikator postaw za pomocą MediaPipe Colab, oraz pokazujemy działający klasyfikator w naszej przykładowej aplikacji ML Kit.
Jeśli nie znasz Google Colaboratory, zapoznaj się z przewodnikiem wprowadzającym.
Do rozpoznawania póz używamy algorytmu najbliższych sąsiadów, ponieważ jest on prosty i łatwy do rozpoczęcia. Algorytm określa klasę obiektu na podstawie najbliższych próbek w zbiorze szkoleniowym.
Aby utworzyć i wytrenować moduł rozpoznawania, wykonaj te czynności:
1. Zbieranie przykładów 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 zebrać próbki, które obejmują różne kąty kamery, warunki środowiskowe, kształty ciała i wariacje ćwiczeń.
2. Uruchom wykrywanie pozycji na przykładowych obrazach
W ten sposób powstaje 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ć właśnie uzyskane punkty orientacyjne pozy.
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, aby uzyskać dostęp do kodu klasyfikatora i przeprowadzić szkolenie modelu.
Aby policzyć powtórzenia, użyliśmy innego algorytmu Colab do monitorowania progu prawdopodobieństwa docelowej pozycji postawy. 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 spadnie poniżej progu, algorytm oznacza, że klasa postawy „w dół” została zamknięta, i zwiększa licznik.
4. Integracja z aplikacją ML Kit
Powyższy kod Colab generuje plik CSV, w którym możesz podać całą ustaloną pozycję przykłady. Z tej sekcji dowiesz się, jak zintegrować plik CSV z aplikacją quickstart ML Kit na Androida, aby wyświetlać klasyfikację niestandardowych póz 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 funkcji PoseClassifierProcessor zaktualizuj zmienne
POSE_SAMPLES_FILE
iPOSE_CLASSES
, aby pasowały do pliku CSV i próbek pozy. - Skompiluj i uruchom 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 spróbować samodzielnie, skorzystaj z MediaPipe Colab i przewodnika po klasyfikacji MediaPipe.
rozpoznawanie prostych gestów przez obliczanie odległości do punktu orientacyjnego;
Jeśli 2 lub więcej punktów orientacyjnych znajduje się blisko siebie, można ich użyć do rozpoznawania gestów. Jeśli na przykład punkt orientacyjny odpowiadający co najmniej jednemu palcu na dłoni jest blisko punktu orientacyjnego odpowiadającego nosowi, można wywnioskować, że użytkownik najprawdopodobniej dotyka twarzy.
rozpoznawanie pozycji jogi za pomocą heurystyki kąta;
Możesz określić pozycję jogi, obliczając kąty różnych stawów. Na przykład rysunek 2 poniżej przedstawia pozycję jogi Wojownik II. Przybliżone kąty, które identyfikują tę pozę, są podane w tych formatach:
Ta pozycja może zostać opisana w ten sposób: kąty części:
- Kąt pod kątem obu ramion
- 180 stopni w obu łokciach
- Kąt 90° w przypadku przedniej części nogi i talii
- Kąt pod kątem 180 stopni w tylnej części kolana
- Kąt pod kątem 135 stopni w talii
Aby obliczyć te kąty, możesz użyć punktów orientacyjnych pozy. Na przykład kąt na prawej nodze z przodu i na wysokości talii to kąt między linią od prawego ramienia do prawego biodra i linią 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ą. Najlepsze wyniki uzyskasz, jeśli zrobisz zdjęcie z boku, z przodu i w poziomie. 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 punktów orientacyjnych na urządzeniach z Androidem
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 punktów orientacyjnych na iOS
W tej metodzie obliczany jest kąt między dowolnymi trzema punktami orientacyjnymi. 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 w prawym 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]];