ML Kit Pose Detection API ile anlamlı yorumlar elde edebilirsiniz Vücudun çeşitli kısımlarının göreli konumlarını kontrol ederek pozun farklı kısımlarını kontrol edebilirsiniz. Bu sayfa birkaç örnek gösteriyor.
K-NN algoritması ile poz sınıflandırma ve tekrar sayımı
Poz algılamanın en yaygın uygulamalarından biri fitness takibidir. Belirli fitness pozlarını tanıyan ve tekrarları sayan bir poz sınıflandırıcı oluşturmak geliştiriciler için zorlu bir iş olabilir.
Bu bölümde, MediaPipe Colab'ı kullanarak özel bir duruş sınıflandırıcıyı nasıl oluşturduğumuzu açıklıyor ve ML Kit örnek uygulamamızda çalışan bir sınıflandırıcıyı gösteriyoruz.
Google Colaboratory hakkında bilginiz yoksa lütfen şu sayfaya göz atın: giriş rehberine göz atın.
Pozları tanımak için k-en yakın komşular algoritmasını (k-NN) kullanırız. ve kolayca başlayabilirsiniz. Algoritma, şu bilgilere göre nesnenin sınıfını belirler: en yakın örnekleri içerir.
Tanıyıcıyı oluşturmak ve eğitmek için şu adımları uygulayın:
1. Resim örnekleri toplama
Hedef egzersizlerin görüntü örneklerini çeşitli kaynaklardan topladık. Her egzersiz için birkaç yüz resim seçtik (ör. şınav için "yukarı" ve "aşağı" pozisyonları). Farklı kamera açıları, ortam koşulları, vücut şekilleri ve egzersiz varyasyonlarını kapsayan örnekler toplamak önemlidir.
2. Örnek görüntülerde poz algılamayı çalıştır
Bu işlem, eğitim için kullanılacak bir dizi duruş yer işareti oluşturur. Biz, çünkü poz algılamayla ilgili ayrıntılı eğitimlere sahip olacağız. modelinize göz atın.
Özel poz sınıflandırması için seçtiğimiz k-NN algoritmasında her örneklem için özellik vektörü gösterimi ve hesaplanacak bir metrik poz örneğine en yakın hedefi bulmak için iki vektör arasındaki mesafeyi ölçer. Bu nedenle, yeni aldığımız poz yer işaretlerini dönüştürmemiz gerekir.
Pozdaki önemli noktaları bir özellik vektörüne dönüştürmek için, iki yönlü mesafeleri kullanırız önceden tanımlanmış poz eklemleri listeleri arasında (örneğin, bilek ve bilek arasındaki mesafe) omuz, ayak bileği, kalça, sol ve sağ bilekler. Resimlerin ölçeği değişiklik gösterebileceğinden, yer işaretlerini dönüştürmeden önce pozları aynı gövde boyutuna ve dikey gövde yönelimine sahip olacak şekilde normalleştirdik.
3. Modeli eğitme ve tekrarları sayma
Sınıflandırıcının koduna erişmek ve modeli eğitmek için MediaPipe Colab'ı kullandık.
Tekrarları saymak için hedef poz pozisyonunun olasılık eşiğini izlemek üzere başka bir Colab algoritması kullandık. Örneğin:
- "Aşağı" duruş sınıfının olasılığı ilk kez belirli bir eşiği geçtiğinde algoritma, "aşağı" duruş sınıfının girildiğini işaretler.
- Olasılık eşiğin altına düştüğünde algoritma, "aşağı" poz sınıfından çıkıldığını işaretler ve sayacı artırır.
4. ML Kit hızlı başlangıç uygulamasıyla entegrasyon
Yukarıdaki Colab, tüm pozlarınızla doldurabileceğiniz bir CSV dosyası oluşturur. kullanabilirsiniz. Bu bölümde, özel poz sınıflandırmasını anlık olarak görmek için CSV dosyanızı ML Kit Android hızlı başlangıç uygulamasıyla nasıl entegre edeceğinizi öğreneceksiniz.
Hızlı başlangıç uygulamasında bulunan örneklerle duruş sınıflandırmasını deneyin
- ML Kit Android hızlı başlangıç kılavuzu uygulama projesini edinin. iyi derlendiğinden ve çalıştığından emin olun.
LivePreviewActivity
bölümüne gidin ve Ayarlar sayfasından Pozisyon Algılama'yıRun classification
etkinleştirin. Artık şınav ve squat'ı sınıflandırabilirsiniz.
Kendi CSV dosyanızı ekleme
- CSV dosyanızı uygulamanın öğe klasörüne ekleyin.
- PoseClassifierProcessor'da,
POSE_SAMPLES_FILE
vePOSE_CLASSES
değişkenlerini CSV dosyası ve poz örnekleri. - Uygulamayı derleyip çalıştırın.
Yeterli örnek olmadığında sınıflandırmanın iyi sonuç vermeyebileceğini unutmayın. Genellikle poz dersi başına yaklaşık 100 örneğe ihtiyacınız vardır.
Daha fazla bilgi edinmek ve bunu kendiniz denemek için MediaPipe Colab ve MediaPipe sınıflandırma kılavuzuna göz atın.
Önemli nokta mesafesini hesaplayarak basit hareketleri tanıma
İki veya daha fazla önemli nokta birbirine yakın olduğunda, bu noktalar hareketleri tanıyalım. Örneğin, bir konumdaki bir veya daha fazla parmağınızla bir el simgesi burundaki belirgin noktaya yakınsa, kullanıcının en çok muhtemelen yüzlerine dokunurlar.
Açı keşifleriyle yoga duruşlarını tanıma
Çeşitli eklemlerin açılarını hesaplayarak yoga pozlarını tanımlayabilirsiniz. Örneğin, aşağıdaki Şekil 2'de, Savaşçı II yoga pozu gösterilmektedir. Yaklaşık açılar şu karakterlerle yazılmıştır:
Bu poz, aşağıdaki yaklaşık vücut kombinasyonu olarak açıklanabilir parça açıları:
- Her iki omuz da 90 derecelik açıda
- Her iki dirsek de 180 derece
- Ön bacak ve bel 90 derecelik açıda
- Arka dizde 180 derece açı
- Belde 135 derecelik açı
Bu açıları hesaplamak için poz yer işaretlerini kullanabilirsiniz. Örneğin, açı belde, sağ ön bacakta ve belde, sağ taraftaki çizgi arasındaki açıdır. kalçadan sağ kalçaya kadar uzanan çizgiyi kapsar.
Pozu belirlemek için gereken tüm açıları hesapladıktan sonra, bir eşleşme olup olmadığına bakın. Bu durumda, pozu tanımış olursunuz.
Aşağıdaki kod snippet'inde, iki vücut parçası arasındaki açıyı hesaplamak için X ve Y koordinatlarının nasıl kullanılacağı gösterilmektedir. Sınıflandırmaya bu yaklaşım bazı sınırlamalar vardır. Yalnızca X ve Y'yi işaretlediğinizde hesaplanan açılar değişir kamera ile özne arasındaki açıya göre ayarlanır. Her e-postada doğrudan bir resimle en iyi sonuçları elde edebilirsiniz. Ayrıca transkriptinizi Z koordinatı daha iyi performans gösterip göstermediğine bakın.
Android'de önemli yer açılarını hesaplama
Aşağıdaki yöntem, herhangi üç yer işareti arasındaki açıyı hesaplar. Döndürülen açının 0 ile 180 derece arasında olmasını sağlar.
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; }
Sağ kalçadaki açı şu şekilde hesaplanabilir:
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));
iOS'ta önemli nokta açıları hesaplama
Aşağıdaki yöntemde, herhangi bir üç alan arasındaki açı hesaplanır önemli noktalardır. Döndürülen açının 0 ile 180 derece arasında olmasını sağlar.
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; }
Sağ kalçadaki açıyı hesaplamak için:
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]];