0

它可能是一个简单/愚蠢的问题,但我在 opencv (android) 中有一个转换问题。

我的目标是从两个连续图像的相应匹配中计算 basicMatrix。

到目前为止,我对此进行了编程(并且正在工作):

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。

现在我将根据彼此匹配的点计算基础矩阵。因此,我必须知道在第二张图像(actKP)中找到了第一张图像(prevKP)中的哪些关键点。

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

第一个问题:如何将 MatOfKeyPoints 提取/转换为 MatOfPoint2f(它们可以传递给 findFundamentalMatrix)

第二个问题:如何仅将匹配的关键点传递给函数 findFundamentalMatrix。这是一个好方法吗?

非常感谢提前!

编辑

非常感谢您的详细回复!我把你的代码写成两个函数:

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() 在函数 cv::Mat cv::findFundamentalMat(...

我证明了 prevPts 和 nextPts 低于 10 分(对于 ransac)。所以我猜错误是这些点是浮点数。但我用调试器检查了这些点是浮点数。

您建议的代码行:

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

应该将点转换为浮点还是我错了?

再次感谢

4

1 回答 1

6

不幸的是,没有比遍历所有匹配项并将值复制到新的 Mat(或向量)更好的方法(即使在 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 回答