0

単純でばかげた質問かもしれませんが、opencv(android)で変換の問題があります。

私の目標は、2つの連続する画像からの対応する一致から基本行列を計算することです。

私はこれまでにこれをプログラムしました(そして動作しています):

detector.detect(actImg, actKP);
detector.detect(prevImg, prevKP);
descExtractor.compute(prevImg, prevKP, descriptorPrev);
descExtractor.compute(actImg, actKP, descriptorAct);
descMatcher.match(descriptorPrev, descriptorAct, matches);
Features2d.drawMatches(prevImg, prevKP, actImg, actKP,matches, mRgba);

一致するタイプはMatOfDMatchです。

ここで、互いに一致するポイントから基本行列を計算します。したがって、最初の画像(prevKP)のどのキーポイントが2番目の画像(actKP)で見つかったかを知る必要があります。

Mat fundamental_matrix = Calib3d.findFundamentalMat(nextPts, prevPts, Calib3d.FM_RANSAC,3, 0.99);

最初の質問:MatOfKeyPointsをMatOfPoint2fに抽出/変換するにはどうすればよいですか(findFundamentalMatrixに渡すことができます)

2番目の質問:一致したキーポイントのみを関数findFundamentalMatrixに渡す方法。これはそれを行うための良い方法ですか?

よろしくお願いします!

編集

詳細な回答ありがとうございます!私はあなたのコードを2つの関数に書きました:

private MatOfPoint2f getMatOfPoint2fFromDMatchesTrain(MatOfDMatch matches2,
        MatOfKeyPoint prevKP2) {
    DMatch dm[] = matches2.toArray();
    List<Point> lp1 = new ArrayList<Point>(dm.length);
    KeyPoint tkp[] = prevKP2.toArray();
    for (int i = 0; i < dm.length; i++) {
        DMatch dmm = dm[i];
        if (dmm.trainIdx < tkp.length) 
            lp1.add(tkp[dmm.trainIdx].pt);
    }
    return new MatOfPoint2f(lp1.toArray(new Point[0]));
}

private MatOfPoint2f getMatOfPoint2fFromDMatchesQuery(MatOfDMatch matches2,
        MatOfKeyPoint actKP2) {
    DMatch dm[] = matches2.toArray();
    List<Point> lp2 = new ArrayList<Point>(dm.length);
    KeyPoint qkp[] = actKP2.toArray();
    for (int i = 0; i < dm.length; i++) {
        DMatch dmm = dm[i];
        if (dmm.queryIdx < qkp.length)
            lp2.add(qkp[dmm.queryIdx].pt);
    }
    return new MatOfPoint2f(lp2.toArray(new Point[0]));
}

しかし、私が呼んでいるとき

prevPts = getMatOfPoint2fFromDMatchesTrain(matches, prevKP);
nextPts = getMatOfPoint2fFromDMatchesQuery(matches, actKP);
Mat fundamental_matrix = Calib3d.findFundamentalMat(
        nextPts, prevPts, Calib3d.FM_RANSAC, 3, 0.99);

問題は、エラー-215が発生することです。エラー:

エラー:(-215)npoints> = 0 && points2.checkVector(2)== npoints && points1.type()== points2.type()in function cv :: Mat cv :: findFundamentalMat(.. ..

prevPtsとnextPtsが10ポイント未満であることを証明しました(ransacの場合)。だから私はエラーがポイントがフローティングポイントであるということだと思います。しかし、これらのポイントが浮動小数点であることをデバッガーで確認しました。

提案されたコードライン:

return new MatOfPoint2f(lp2.toArray(new Point[0]));

ポイントを浮動小数点に変換する必要がありますか、それとも間違っていますか?

再度、感謝します

4

1 に答える 1

6

残念ながら、(C ++ APIでも)すべての一致をループして値を新しいマット(またはベクトル)にコピーするよりも良い方法はありません。

Javaでは、次のように実行できます。

DMatch dm[] = matches.toArray();
List<Point> lp1 = new ArrayList<Point>(dm.length);
List<Point> lp2 = new ArrayList<Point>(dm.length);
KeyPoint tkp[] = prevKP.toArray();
KeyPoint qkp[] = actKP.toArray();
for (int i = 0; i < dm.length; i++) {
    DMatch dm = dm[i];
    lp1.add(tkp[dm.trainIdx].pt);
    lp2.add(qkp[dm.queryIdx].pt);
}

MatOfPoint2f pointsPrev = new MatOfPoint2f(lp1.toArray(new Point[0]));
MatOfPoint2f pointsAct  = new MatOfPoint2f(lp2.toArray(new Point[0]));
于 2012-12-06T22:31:20.130 に答える