opencv java match_Java OpenCV-从knnMatch提取匹配项

小编典典

如其他答案所述,有几种方法可以消除异常值和不良匹配项。我猜您找到了示例和教程,match而不是knnMatch利用其中的一些方法。

因此,您可能知道不同之处在于knnMatch,descriptor2针对中的每个描述符返回n个最佳匹配descriptor1。这意味着,您将获得匹配列表的列表,而不是匹配列表。我想这就是您遇到问题的原因。

使用的主要优点knnMatch是可以执行比率测试。因此,如果从一个描述符输入descriptor1到两个最佳描述符的descriptor2距离相似,则表明图像中存在重复的图案(例如,草丛前的栅栏尖端)。因此,此类匹配不可靠,应将​​其删除。(我不确定为什么要搜索五个最佳匹配-

knnMatch每个描述符将5传递给-。而是搜索两个。)

如果现在只想访问每个描述符的最佳匹配,则只需要访问“子列表”的第一个元素。在下面的示例中,您将找到使用RANSAC进行比率测试和单应性估计的示例(我在替换了所有内容knnMatch):

// ratio test

LinkedList good_matches = new LinkedList();

for (Iterator iterator = matches.iterator(); iterator.hasNext();) {

MatOfDMatch matOfDMatch = (MatOfDMatch) iterator.next();

if (matOfDMatch.toArray()[0].distance / matOfDMatch.toArray()[1].distance < 0.9) {

good_matches.add(matOfDMatch.toArray()[0]);

}

}

// get keypoint coordinates of good matches to find homography and remove outliers using ransac

List pts1 = new ArrayList();

List pts2 = new ArrayList();

for(int i = 0; i

pts1.add(keypoints1.toList().get(good_matches.get(i).queryIdx).pt);

pts2.add(keypoints2.toList().get(good_matches.get(i).trainIdx).pt);

}

// convertion of data types - there is maybe a more beautiful way

Mat outputMask = new Mat();

MatOfPoint2f pts1Mat = new MatOfPoint2f();

pts1Mat.fromList(pts1);

MatOfPoint2f pts2Mat = new MatOfPoint2f();

pts2Mat.fromList(pts2);

// Find homography - here just used to perform match filtering with RANSAC, but could be used to e.g. stitch images

// the smaller the allowed reprojection error (here 15), the more matches are filtered

Mat Homog = Calib3d.findHomography(pts1Mat, pts2Mat, Calib3d.RANSAC, 15, outputMask, 2000, 0.995);

// outputMask contains zeros and ones indicating which matches are filtered

LinkedList better_matches = new LinkedList();

for (int i = 0; i < good_matches.size(); i++) {

if (outputMask.get(i, 0)[0] != 0.0) {

better_matches.add(good_matches.get(i));

}

}

// DRAWING OUTPUT

Mat outputImg = new Mat();

// this will draw all matches, works fine

MatOfDMatch better_matches_mat = new MatOfDMatch();

better_matches_mat.fromList(better_matches);

Features2d.drawMatches(img1, keypoints1, img2, keypoints2, better_matches_mat, outputImg);

// save image

Imgcodecs.imwrite("result.jpg", outputImg);

我希望这足以作为一个例子。可以类似地应用其他过滤方法。如果您还有其他问题,请随时询问。

编辑: 单应过滤仅在您的大多数关键点位于场景中的同一平面(例如墙等)上时才有效。

2020-12-03

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值