デジタル信号の処理に問題があります。私は指先を検出しようとしています。ここに提示されている解決策に似ています:Hand and finger detection using JavaCV。コンピュータビジョン - OpenCVによる凸包および凸欠陥のフィルタリング
しかし、私はJavaCVを使用していませんが、Android用のOpenCVは少し異なります。 私はこのチュートリアルで提示されたすべてのステップを実行することができましたが、凸包および凸欠陥のフィルタリングを行いました。ここで
画像は別の解像度である:
あなたがはっきりと見ることができるように、多くの黄色の点(凸包)にありますこれは私のイメージはどのように見えるかですまた、多くの赤い点(凸凹)にも影響します。場合によっては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));
}
}
結果(白のポイント - フィルタリング後の指先):
Cフィルタリングのために適切な関数を書くのを助けてくれますか?
UPDATE 2013年8月14日
私は、輪郭近似のための標準的なOpenCVの関数を使用します。私は、解像度の変更と手でカメラの距離を近似値を変更する必要がありますが、それはかなり難しいです。解像度がより小さい場合、指はより少ないピクセルから構成され、したがって近似値は恋人でなければならない。距離と同じです。それを高く保つと指が完全に失われます。されるであろう、
Imgproc.approxPolyDP(frame, frame, 2 , true);
私は高い値を使用する場合、結果は下の画像のようなものです:だから私は、しかし、小さな値は、計算を高速化するために有用である可能性近似は、問題を解決するための良い方法はないと思います距離と解像度が変わらない場合にのみ良い。 また、船体点と欠陥点のデフォルトの方法では、(最小角度、距離など)渡すための有用な引数がないことに非常に驚いています...
以下の画像は、解像度または手とカメラの距離とは無関係に、常に達成したいという効果を示しています。また、私は私が私の手のひらを閉じたときに、すべてをまとめると...
を任意の黄色の点を表示したくない、私が知りたいのです:
- どのようにすることができますポイント
- をフィルタリングする方法OpenCVで使用されているデータ構造について誰かが知っているか(グラフィック表示、解説)している場合は、いつも動作する解像度と距離に依存しない近似を行います。 (マット、MatOfInt、MatOfPoint、MatOfPoint2、MatOfPoint4など)
私は近似値(更新後の)を行うの創設者、それでも結果は受け入れられないが(時々、私はまだ、指先で複数のポイントを取得します。また、近似の大きさは解像度と手間とカメラの距離に依存する必要がありますが、これは非常に難しいものです。 – Marek