デジタル信号の処理に問題があります。ここに提示されているソリューションと同様に、指先を検出しようとしています: JavaCVを使用した手と指の検出 。
しかし、私はJavaCVを使用していませんが、AndroidのOpenCVを使用しています。これは少し異なります。チュートリアルで提示されているすべてのステップを実行できましたが、凸包と凸欠陥のフィルタリングです。これは私の画像は次のようになります:
これは別の解像度の画像です:
はっきりとわかるように、黄色の点(凸包)が多く、赤色の点(凸効果)も多くあります。 2つの黄色の点の間に赤い点がない場合がありますが、これはかなり奇妙です(どのように凸包を計算するのですか?)
私が必要なのは、以前に提供されたリンクのように、OpenCVのデータ構造を使用して類似のフィルタリング関数を作成することです。
凸包はMatOfIntのタイプです...凸欠陥はMatOfInt4のタイプです...
愚かなOpenCVが同じデータを含む異なるタイプのデータを異なる方法で使用するため、私はいくつかの追加のデータ構造も作成しました...
convexHullMatOfInt = new MatOfInt();
convexHullPointArrayList = new ArrayList<Point>();
convexHullMatOfPoint = new MatOfPoint();
convexHullMatOfPointArrayList = new ArrayList<MatOfPoint>();
これが私がこれまでに行ったことですが、うまく機能していません。問題はおそらくデータを間違った方法で変換することです:
凸包と凸欠陥の作成:
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));
}
}
結果(白い点-フィルタリング後の指先):
フィルタリングのための適切な関数を書くのを手伝ってくれませんか?
2013年8月14日更新
輪郭近似には標準のopenCV関数を使用しています。解像度の変更や手からカメラまでの距離に応じて近似値を変更する必要がありますが、これは非常に困難です。解像度が小さい場合、指はより少ないピクセルで構成されているため、近似値は低いほうがよいでしょう。距離も同じです。高く保つと指が完全に失われます。したがって、問題を解決するには近似は適切なアプローチではないと思いますが、小さい値は計算を高速化するのに役立ちます。
Imgproc.approxPolyDP(frame, frame, 2 , true);
高い値を使用すると、結果は下の画像のようになります。これは、距離と解像度が変わらない場合にのみ適しています。 また、ハルポイントと欠陥ポイントのデフォルトのメソッドには、渡す最小の引数(最小角度、距離など)がないことにも驚いています...
下の画像は、解像度や手とカメラの距離に関係なく、常に実現したい効果を示しています。また、Palmを閉じるときに黄色のポイントを表示したくない...
すべてを要約すると、私は知りたいです:
低解像度での凸包は、全体として手の位置を特定するために使用できます。指には役立ちませんが、関心領域と適切なスケールを提供します。
次に、より高い解像度の分析を近似輪郭に適用します。最後の2つの「長さと角度」の基準を満たさないポイントをスキップするのは簡単ですが、「完全にスキップする」のではなく「平均化する」こともできます。 」.
コード例は、凸状の欠陥を計算してから削除する1つのパスです..これは論理エラーです..進むにつれてポイントを削除する必要があります..(a)1つのパスですべてを実行する方が速くて簡単です( b)削除すると以前の計算が変更されるため、最初のパスでポイントを削除して後で追加し直す必要がなくなります。
この基本的なテクニックは非常にシンプルなので、基本的なオープンPalmで機能します。ただし、本質的には手やジェスチャーを理解しないため、スケール、角度、長さのパラメーターを調整しても、「これまでのところ」しか得られません。
テクニックへの参照:フィルターの長さと角度の「凸欠陥」Simen Andresenブログ 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
「Leap Motion」の創設者である商用製品のDavid HolzとMichael Buckwald http://www.engadget.com/2013/03/11/leap-motion-michael-buckwald-interview/
あなたはその点を逃したと思います:
オリジナルではなく輪郭の低ポリゴン近似を利用することで、船体の作成と欠陥分析が高速化されます。