2010-12-16 8 views
7

WindowsとMacOSX用のKinectとドライバがあります。 OpenCV APIを使用してKinectからストリーミングされたジェスチャ認識の例はありますか?私はDaVinci prototype on Xbox Kinectと似ているが、WindowsとMacOSXでは達成しようとしている。OpenCVを使用して、Kinectからストリーミングされたジェスチャ認識の例はどこで知ることができますか?

+0

これは興味深い問題です。問題を解消すれば解決策を見つけるチャンスが増え、それぞれの問題のオプションを再考することができます。あなたはKinectからどのようなデータを得ることができますか?それはあなたが処理しなければならないビデオストリームですか?この場合、これは一般的なジェスチャ認識の問題に単純化されます。これは非常に活発な研究分野となりそうです。それとも、デバイスのジェスチャー認識ソフトウェアをどうにか活用したいのですか?どちらの場合でも、リンクでデモを実装した人と話すことは、おそらく良いスタートステップになります。 – misha

+0

あなたはCのソースコードを提供できますか? それは大きな助けになるでしょう – Rikki

答えて

-1

kinectからの奥行き画像データはあまり敏感ではないので、これは主に単純なことだと思います。したがって、1mから1.5mの距離の後、すべてのフィンガーがマージされるので、フィンガーを検出するために明確な輪郭を得ることができなくなります。

+2

1.5mの距離で私はまだ私のkinectで私の指を見ることができます。また、OPが共有するビデオでは、プレゼンターがそれより近いことに注意してください。最後に、どのように質問に答えますか? –

15

あなたのリンクからのデモは、実際にジェスチャー認識を使用していないようです。はるかに簡単な2つの異なる手の位置(開閉)を区別し、手の位置を追跡します。彼がデモに手を置いていることを考えると(身体の前で、キネクトが開いているときにキネに向かっている)、ここにはおそらく彼がやっていることがあるでしょう。どの言語を使用しているのか正確には分からなかったので、私はopenCVでCの関数名を使用しますが、他の言語でも同じでなければなりません。また、kinectから深度マップを得ることができると仮定します(おそらく、libfreenectを使用する場合、コールバック関数を介して)。

  1. 十分に近い点(手)を選択する深さの閾値。 あなた自身でも、openCVを使って直接CV_THRESH_BINARYでバイナリイメージ(cvThreshold())を取得することもできます。 スレッシュホールド後に取得した画像を表示し、設定に合うようにしきい値を調整します(この領域に干渉が増えるため、kinectに近すぎないようにしてください)。

  2. cvFindContour(と手の輪郭を取得します)

この基礎。あなたの手の輪郭は、あなたがしたいことに応じて異なる方向を取ることができます。あなただけのオープンとクローズの手の間で検出しない場合は、おそらく行うことができます。

  1. がcvConvexHull2を使用して、手()

  2. にcvConvexityDefect()を使用して凸欠陥を取得する凸包を取得します等高線とあなたが前に持っている凸包です。

  3. 凸欠陥を分析する:大きな欠陥がある場合、手が開いている(形状がフィンガの間に凹形であるため)。手が閉じていない場合。

でも、指を検出することもできます。それは私が先週行ったことです、それはそれ以上の努力を必要とせず、おそらくあなたのデモを高めるでしょう!安価ではありますが、これを行うにはかなり信頼できる方法です。

  1. 多角形で手の輪郭を近似します。輪郭線上でcvApproxPoly()を使用します。できるだけシンプルなポリゴンを持つように精度パラメータを調整する必要がありますが、それは指を一緒にブレンドしません(約15はかなり良いはずですが、取得したものを確認するためにcvDrawContours()を使用して画像に描画します) 。

  2. 輪郭を分析して鋭い凸角を見つけます。あなたは手でそれをしなければならないでしょう。これは最も難しい部分です:

    • openCVで使用されるデータ構造は、最初は少し混乱するかもしれません。 CvSeq構造体に苦労しすぎると、cvCvtSeqToArray()が役に立ちます。
    • あなたは最終的に凸面の角度を見つけるために(基本的な)数学をやります。角度がどれほど鋭いかを決定するためにドットプロダクトを使うことができ、凸と凹の角度を区別するベクトルプロダクトを使うことができます。
  3. ここでは、鋭い凸角があなたの指先です!

これは指を検出する簡単なアルゴリズムですが、これを高める方法はたくさんあります。たとえば、デプスマップにメジアンフィルタを適用して、すべてを少し滑らかにしたり、より正確なポリゴン近似を試みたりして、輪郭をフィルタリングして、指先などで閉じる点をマージすることができます。

幸運と楽しい!

0

mage dest = new Image(this.bitmap.Width、this.bitmap。高さ); CvInvoke.cvThreshold(src、dest、220、300、Emgu.CV.CvEnum.THRESH.CV_THRESH_BINARY); ビットマップnem1 =新しいビットマップ(dest.Bitmap)。 this.bitmap = nem1; グラフィックスg = Graphics.FromImage(this.bitmap);

   using (MemStorage storage = new MemStorage()) //allocate storage for contour approximation 
        for (Contour<Point> contours = dest.FindContours(); contours != null; contours = contours.HNext) 
        { 
         g.DrawRectangle(new Pen(new SolidBrush(Color.Green)),contours.BoundingRectangle); 
         // CvInvoke.cvConvexHull2(contours,, Emgu.CV.CvEnum.ORIENTATION.CV_CLOCKWISE, 0); 
         IntPtr seq = CvInvoke.cvConvexHull2(contours,storage.Ptr, Emgu.CV.CvEnum.ORIENTATION.CV_CLOCKWISE, 0); 
         IntPtr defects = CvInvoke.cvConvexityDefects(contours, seq, storage); 
         Seq<Point> tr= contours.GetConvexHull(Emgu.CV.CvEnum.ORIENTATION.CV_CLOCKWISE); 

         Seq<Emgu.CV.Structure.MCvConvexityDefect> te = contours.GetConvexityDefacts(storage, Emgu.CV.CvEnum.ORIENTATION.CV_CLOCKWISE); 
         g.DrawRectangle(new Pen(new SolidBrush(Color.Green)), tr.BoundingRectangle); 
         //g.DrawRectangle(new Pen(new SolidBrush(Color.Green)), te.BoundingRectangle); 

        } 

は、私はあなたのアルゴリズムに従ってやったが、それは何を絞っている 動作しませんか?

関連する問題