2013-08-09 9 views
45

デジタル信号の処理に問題があります。私は指先を検出しようとしています。ここに提示されている解決策に似ています:Hand and finger detection using JavaCVコンピュータビジョン - OpenCVによる凸包および凸欠陥のフィルタリング

しかし、私はJavaCVを使用していませんが、Android用のOpenCVは少し異なります。 私はこのチュートリアルで提示されたすべてのステップを実行することができましたが、凸包および凸欠陥のフィルタリングを行いました。ここで

Resolution 640x480

画像は別の解像度である:

Resolution 320x240

あなたがはっきりと見ることができるように、多くの黄色の点(凸包)にありますこれは私のイメージはどのように見えるかですまた、多くの赤い点(凸凹)にも影響します。場合によっては2つの黄色点の間に赤点がありません(凸包はどのように計算されますか)。

私が必要とするのは、OpenCVのデータ構造を使用する前のリンクのようなsimillarフィルタリング関数を作成することです。

凸包はMatOfIntのタイプです... コンベクシティ欠陥がMatOfInt4のタイプです...

愚かなのOpenCVは異なる方法で、同じデータを含むさまざまな種類のデータを使用していますので、私は、また、いくつかの追加のデータ構造を作成しました...

これはここまでですが、うまくいきません。問題は、間違った方法でデータを変換すると、おそらくです:

凸包と凸欠陥を作成:

public void calculateConvexHulls() 
{ 
    convexHullMatOfInt = new MatOfInt(); 
    convexHullPointArrayList = new ArrayList<Point>(); 
    convexHullMatOfPoint = new MatOfPoint(); 
    convexHullMatOfPointArrayList = new ArrayList<MatOfPoint>(); 

    try { 
     //Calculate convex hulls 
     if(aproximatedContours.size() > 0) 
     { 
      Imgproc.convexHull(aproximatedContours.get(0), convexHullMatOfInt, false); 

      for(int j=0; j < convexHullMatOfInt.toList().size(); j++) 
       convexHullPointArrayList.add(aproximatedContours.get(0).toList().get(convexHullMatOfInt.toList().get(j))); 
      convexHullMatOfPoint.fromList(convexHullPointArrayList); 
      convexHullMatOfPointArrayList.add(convexHullMatOfPoint);  
     } 
    } catch (Exception e) { 
     // TODO Auto-generated catch block 
     Log.e("Calculate convex hulls failed.", "Details below"); 
     e.printStackTrace(); 
    } 
} 

public void calculateConvexityDefects() 
{ 
    mConvexityDefectsMatOfInt4 = new MatOfInt4(); 

    try { 
     Imgproc.convexityDefects(aproximatedContours.get(0), convexHullMatOfInt, mConvexityDefectsMatOfInt4); 

     if(!mConvexityDefectsMatOfInt4.empty()) 
     { 
      mConvexityDefectsIntArrayList = new int[mConvexityDefectsMatOfInt4.toArray().length]; 
      mConvexityDefectsIntArrayList = mConvexityDefectsMatOfInt4.toArray(); 
     } 
    } catch (Exception e) { 
     Log.e("Calculate convex hulls failed.", "Details below"); 
     e.printStackTrace(); 
    } 
} 

フィルタリング:

public void filterCalculatedPoints() 
    { 
     ArrayList<Point> tipPts = new ArrayList<Point>(); 
     ArrayList<Point> foldPts = new ArrayList<Point>(); 
     ArrayList<Integer> depths = new ArrayList<Integer>(); 

     fingerTips = new ArrayList<Point>(); 

     for (int i = 0; i < mConvexityDefectsIntArrayList.length/4; i++) 
     { 
      tipPts.add(contours.get(0).toList().get(mConvexityDefectsIntArrayList[4*i])); 
      tipPts.add(contours.get(0).toList().get(mConvexityDefectsIntArrayList[4*i+1])); 
      foldPts.add(contours.get(0).toList().get(mConvexityDefectsIntArrayList[4*i+2])); 
      depths.add(mConvexityDefectsIntArrayList[4*i+3]); 
     } 

     int numPoints = foldPts.size(); 
     for (int i=0; i < numPoints; i++) { 
      if ((depths.get(i).intValue()) < MIN_FINGER_DEPTH) 
       continue; 

      // look at fold points on either side of a tip 
      int pdx = (i == 0) ? (numPoints-1) : (i - 1); 
      int sdx = (i == numPoints-1) ? 0 : (i + 1); 

      int angle = angleBetween(tipPts.get(i), foldPts.get(pdx), foldPts.get(sdx)); 
      if (angle >= MAX_FINGER_ANGLE) // angle between finger and folds too wide 
       continue; 

      // this point is probably a fingertip, so add to list 
      fingerTips.add(tipPts.get(i)); 
     } 
    } 

結果(白のポイント - フィルタリング後の指先):

enter image description here

Cフィルタリングのために適切な関数を書くのを助けてくれますか?

UPDATE 2013年8月14日

私は、輪郭近似のための標準的なOpenCVの関数を使用します。私は、解像度の変更と手でカメラの距離を近似値を変更する必要がありますが、それはかなり難しいです。解像度がより小さい場合、指はより少ないピクセルから構成され、したがって近似値は恋人でなければならない。距離と同じです。それを高く保つと指が完全に失われます。されるであろう、

Imgproc.approxPolyDP(frame, frame, 2 , true); 

私は高い値を使用する場合、結果は下の画像のようなものです:だから私は、しかし、小さな値は、計算を高速化するために有用である可能性近似は、問題を解決するための良い方法はないと思います距離と解像度が変わらない場合にのみ良い。 また、船体点と欠陥点のデフォルトの方法では、(最小角度、距離など)渡すための有用な引数がないことに非常に驚いています...

以下の画像は、解像度または手とカメラの距離とは無関係に、常に達成したいという効果を示しています。また、私は私が私の手のひらを閉じたときに、すべてをまとめると...

を任意の黄色の点を表示したくない、私が知りたいのです:

  • どのようにすることができますポイント
  • をフィルタリングする方法OpenCVで使用されているデータ構造について誰かが知っているか(グラフィック表示、解説)している場合は、いつも動作する解像度と距離に依存しない近似を行います。 (マット、MatOfInt、MatOfPoint、MatOfPoint2、MatOfPoint4など)

enter image description here

答えて

0

私はあなたがそのポイントを逃したと思う:

ハルの作成および欠陥分析は、低を利用することによって高速化されていますオリジナルではなく輪郭のポリゴン近似。

+0

私は近似値(更新後の)を行うの創設者、それでも結果は受け入れられないが(時々、私はまだ、指先で複数のポイントを取得します。また、近似の大きさは解像度と手間とカメラの距離に依存する必要がありますが、これは非常に難しいものです。 – Marek

1

低解像度での凸包は、手全体の位置を特定するために使用できますが、指には役立ちませんが、関心領域と適切な縮尺を提供します。

近似した輪郭に高解像度の解析を適用する必要がありますが、代わりに「平均」を使用することもできますが、最後の2つの「長さと角度」の基準を超えない点はスキップしやすくなります「全部スキップ」

あなたのコード例は、凸欠陥を計算してから削除することです。論理エラーです。あなたはポイントを削除する必要があります。(a)すべてを高速化して(b)は、最初のパスでポイントを削除しないようにします。削除すると前の計算が変更されるため、後で追加する必要があります。

この基本的な手法は非常に簡単で、基本的なオープンな手のひらにも機能します。それは本質的に手やジェスチャーを理解するものではありませんので、スケール、角度、長さのパラメータをチューニングすることは、これまでに "これまでのところ"になることはありません。テクニックに

参考文献: フィルタの長さと角度 "コンベクシティ欠陥" Simenアンドレのブログhttp://simena86.github.io/blog/2013/08/12/hand-tracking-and-recognition-with-opencv/

のKinect SDKベースのC#ライブラリを追加指の方向検出 http://candescentnui.codeplex.com/ http://blog.candescent.ch/2011/11/improving-finger-detection.html

「自己成長と組織化と神経ガス "(SGONG) 教授ニコスパパマークスhttp://www.papamarkos.gr/uploaded-files/Hand%20gesture%20recognition%20using%20a%20neural%20network%20shape%20fitting%20technique.pdf

市販品 デビッドホルツ&マイケルBuckwaldの「リープモーション」http://www.engadget.com/2013/03/11/leap-motion-michael-buckwald-interview/