10

ユーザー (理学療法士) が Kinect の前で動きを実行するアプリケーションを開発する必要があります。データの動きをデータベースに書き込み、患者がこの動きを模倣しようとします。システムは、記録された動きと実行された動きの類似性を計算します。

私の最初のアイデアは、記録中(例では5秒ごと)にポイントの位置(x、y、z)を保存し、実行時間(患者ごと)でそれらを比較することです。

このアプローチが単純すぎることはわかっています。サイズが異なる人では骨格の認識が異なるため、比較は信頼できないと思います。

私の質問は、保存されたモーションを(その場で)実行された動きと比較する最良の方法についてです。

4

2 に答える 2

7

医師のフレームが患者のフレームに投影されるようにしましたが、骨の高さが異なるため、スケルトン全体ではうまく機能しません :/. コードはここにあります。これはベータ 2 コードです。最新バージョンは ここにありますが、現在は完全には機能していません。

比較に関しては、このようなことをしてください

for (int i = 0; i < patientList.Count; i++)
{
    int diff = (int)Math.Abs(patientList[i] - doctorList[i]);

    if (diff < 100) //or whatever number you want
    {
         Debug.WriteLine("Good Job");
    }
}

Fixus によって言及された骨の高さのために、私は全体の図のアイデアを放棄したので、私の現在のプログラムは次のようになります: 画像

編集

これは、kinect で 2 つの動きを比較し、2 つの動きの類似性を計算するという概念です。詳しく説明します。

点 A (0, 0, 0) と点 B (1, 1, 1) の 2 つの点があるとします。ここで、点 A から点 B までの差を見つけたいので、X、Y、Z のすべての数値を引くと、差は 1 X 1 Y 1 Z になります。これは簡単なことです。今すぐ実装します。が上に書いたコードは、このように実装します。

//get patient hand coordinates
double patienthandX = Canvas.GetLeft(patienthand);
double patienthandY = Canvas.GetTop(patienthand);

//get doctor hand coordinates
double doctorhandX = Canvas.GetLeft(doctorhand);
double doctorhandY = Canvas.GetTop(doctorhand);

//compare difference for each x and y
//take Absolute value so that it is positive
double diffhandX = Math.Abs(patienthandX - doctorhandX);
double diffhandY = Math.Abs(patienthandY - doctorhandY);

ここで別の問題が発生します。医師の座標は常に同じですが、医師の座標が記録された場所に患者が立っていない場合はどうなるでしょうか。次に、より単純な数学を実装します。この簡単な例を見てみましょう。点 A(8, 2) を点 B(4, 12) に移動するとします。A の x と y を掛けると B になります。X を 0.5 倍し、Y を 6 倍します。Kinect の場合、患者の腰に要素を配置し、これを医師の腰と比較します。 . 次に、すべてのドクター ジョイントにその数を掛けて、患者の上にドクター ジョイントを (多かれ少なかれ) 配置します。例えば

double whatToMultiplyX = (double) doctorhipX / patienthipX;
double whatToMultiplyY = (double) doctorhipY / patienthipY;

これはすべて非常に単純ですが、それをまとめるのが難しい部分です。これまでのところ、1) 医師のフレームを患者のフレームの上にスケーリングし、2) 差を計算します。3) レップ全体の違いを比較します。4) 次の担当者のためにリセットします。これは単純に思えますが、そうではありません。担当者の差全体を計算するには、次のようにします。

//get patient hand coordinates
double patienthandX = Canvas.GetLeft(patienthand);
double patienthandY = Canvas.GetTop(patienthand);

//get doctor hand coordinates
double doctorhandX = Canvas.GetLeft(doctorhand);
double doctorhandY = Canvas.GetTop(doctorhand);

//compare difference for each x and y
//take Absolute value so that it is positive
double diffhandX = Math.Abs(patienthandX - doctorhandX);
double diffhandY = Math.Abs(patienthandY - doctrorhandY);

//+= so that it keeps adding to it.
totaldiffhandX += diffhandX;
totaldiffhandY += diffhandY;

これで比較して、次のように言えます。

if (totaldiffhandX < 1000 && totaldiffhandY < 1000) //keep numbers pretty high since it is an entire rep
{
     //reset difference
     totaldiffhandX = 0;
     totaldiffhandY = 0;

     //tell the patient good job
     Debug.WriteLine("Good Job");
}

これは非常に簡単ですが、すべてのジョイントの x と y に対してこれを行う必要があることに注意してください。そうしないと機能しません。お役に立てれば。

于 2012-07-11T22:16:25.420 に答える
4

まず第一に、人は違うということを覚えておいてください。身長、幅、体重、骨の長さなどは人それぞれ異なります。

あなたのコードは、おそらくこれが原因で機能しません。

第二に、もっと幾何学的に考える必要があります。点だけではなく、ベクトルとその方向で考えてください。それぞれの動きは、いくつかの方向へのいくつかのベクトルの動きです。次に割合。ユーザーごとにアプリケーションを構成する必要があります。

あなたにはいくつかのパターンがあります。パターはあなたの理学療法士です。彼の動きだけでなく、彼の体も覚えておく必要があります。腕の長さ、脚の長さ、距離など。アプリを使用する各ユーザーも測定する必要があります。このすべてのデータがあれば、サイズをスケーリングし、移動の方向を比較することで動きを比較できます

もちろん、たとえば次のような非常に単純な動きがあることを覚えておいてください。それらは、手の実際の位置と動きの方向を確認することにより、簡単な数学で認識できます。この3つのコントロールポイントが必要で、家にいます:)

ジェスチャ認識は簡単なことではありません

于 2012-07-12T05:44:47.433 に答える