它可能是一个简单/愚蠢的问题,但我在opencv(android)中有转换问题。
我的目标是从两个连续的图像中计算出相应匹配的基本矩阵。
我编程到目前为止(和工作):
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。 这是一个很好的方式吗?
非常感谢advace!
修改
非常感谢您的详细回复! 我把你的代码编写成两个函数:
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&gt; = 0&amp;&amp; points2.checkVector(2)== npoints&amp;&amp;函数cv :: Mat中的points1.type()== points2.type() CV :: findFundamentalMat(...
我证明prevPts和nextPts低于10分(对于ransac)。 所以我猜这个错误就是积分和浮点数。但我用调试器检查了这些点是浮点数。
您建议的代码行:
return new MatOfPoint2f(lp2.toArray(new Point[0]));
应该将点转换为浮点还是我错了?
再次感谢
答案 0 :(得分: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]));