7

私はKinectとWindowsとMacOSX用のドライバーを持っています。OpenCV APIを使用してKinectからストリーミングされたジェスチャ認識の例はありますか?Xbox KinectでDaVinciプロトタイプに似たものを実現しようとしていますが、WindowsとMacOSXで実現しようとしています。

4

3 に答える 3

15

リンクからのデモは、実際のジェスチャ認識を使用していないようです。2つの異なる手の位置(開いた/閉じた)を区別するだけで、はるかに簡単で、手の位置を追跡します。彼がデモで手を握る方法(体の前で、開いているときにKinectに面している)を考えると、おそらくこれが彼が行っていることです。使用している言語が正確ではなかったため、openCVではC関数名を使用しますが、他の言語でも同様である必要があります。また、kinectから深度マップを取得できると仮定します(libfreenectを使用している場合はおそらくコールバック関数を介して)。

  1. 十分に近いポイント(手)のみを選択するための深さのしきい値。これは、自分で行うことも、openCVを直接使用してバイナリイメージを取得することもできます(CV_THRESH_BINARYを使用したcvThreshold())。しきい値処理後に取得した画像を表示し、構成に合わせてしきい値を調整します(この領域では干渉が大きくなるため、kinectに近づきすぎないようにしてください)。

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

これが基本です。手の輪郭ができたので、やりたいことに応じて、さまざまな方向に進むことができます。手を開いているか閉じているかを検出したいだけの場合は、おそらく次のことができます。

  1. cvConvexHull2()を使用して手の凸包を取得します

  2. 前に取得した輪郭と凸包でcvConvexityDefect()を使用して凸包を取得します。

  3. 凸面の欠陥を分析します。大きな欠陥がある場合は手を開いており(指の間の形状が凹面であるため)、そうでない場合は手を閉じています。

ただし、指の検出も可能です。それは私が先週行ったことです、それはそれほど多くの努力を必要とせず、おそらくあなたのデモを後押しするでしょう!それを行うための安価ですがかなり信頼できる方法は次のとおりです。

  1. 手の輪郭をポリゴンで近似します。等高線でcvUsingPoly()を使用します。ポリゴンをできるだけ単純にするために精度パラメータを調整する必要がありますが、それでは指が混ざりません(15前後はかなり良いはずですが、cvDrawContours()を使用して画像に描画し、取得したものを確認してください) 。

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

    • openCVで使用されるデータ構造は、最初は少し混乱するかもしれません。CvSeq構造に苦労しすぎる場合は、cvCvtSeqToArray()が役立つ場合があります。
    • 最後に、凸角を見つけるためにいくつかの(基本的な)計算を行うことができます。内積を使用して角度の鋭さを決定し、ベクトル積を使用して凸角と凹角を区別できることを忘れないでください。
  3. さあ、鋭い凸角が指先です!

これは指を検出するための単純なアルゴリズムですが、それを後押しする方法はたくさんあります。たとえば、深度マップにメジアンフィルタを適用してすべてを少し「滑らか」にするか、より正確なポリゴン近似を使用してから、等高線をフィルタリングして指先で閉じるポイントをマージすることができます。 。

頑張って楽しんでね!

于 2010-12-18T09:23:05.637 に答える
0

mage dest = new Image(this.bitmap.Width、this.bitmap.Height); CvInvoke.cvThreshold(src、dest、220、300、Emgu.CV.CvEnum.THRESH.CV_THRESH_BINARY); ビットマップnem1=new Bitmap(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);

                    }

私はあなたのアルゴリズムに従って行いましたが、機能しません。絞りとは何ですか?

于 2011-01-26T08:49:49.177 に答える
-1

kinectからの深度画像データはそれほど感度が高くないため、これほど単純なことではないと思います。したがって、1mから1.5mの距離を過ぎると、すべての指が結合されるため、指を検出するための明確な輪郭を取得できなくなります。

于 2011-01-04T08:21:22.020 に答える