【发布时间】:2017-11-20 06:13:17
【问题描述】:
我在尝试让 perspectiveTransform() 产生我能理解的结果时遇到了问题。
我正在编写一个图像匹配应用程序。这些图像大部分是绘画。我匹配的是整体,整体,部分,甚至部分。分辨率会有所不同。由于这种关系,通常使用的“对象”“场景”术语不适合。因为对象实际上可以是场景,反之亦然。所以我使用查询图像和目标索引图像来描述查询和我要匹配的图像。
我一直在关注各种 OpenCV 教程,了解如何将一张图像与另一张图像匹配,然后使用 perspectiveTransform 能够在识别的图像上放置一个边界框……但我遇到了问题。
在添加到此的图像中,我们可以看到我有一个整体的关系。 作为 SIFT 过程的一部分,图像已被缩放到最大边缘 1000 并转换为灰度。
Query image dimensions x=1000, y=750
Idx image dimensions x=667, y=1000
Initial Flann matches: 501
After Lowe's 2nd nn ratio: 48 matches
RANSAC inliers: 37 matches
代码..
homography = Calib3d.findHomography(idxMatOfPoint2f, queryMatOfPoint2f, Calib3d.RANSAC, 5, mask, 2000, 0.995);
Mat query_corners = new Mat(4, 1, CvType.CV_32FC2);
Mat idx_corners = new Mat(4, 1, CvType.CV_32FC2);
query_corners.put(0, 0, new double[]{0, 0});
query_corners.put(1, 0, new double[]{queryImage.cols() - 1, 0});
query_corners.put(2, 0, new double[]{queryImage.cols() - 1, queryImage.rows() - 1});
query_corners.put(3, 0, new double[]{0, queryImage.rows() - 1});
Core.perspectiveTransform(query_corners, idx_corners, homography);
这段代码的结果给出了以下数据(原始 x,y : 转换后的 x,y )
Corners - Top-left = 0.0,0.0 : 163.84683227539062,167.56898498535156
Corners - Top-right = 999.0,0.0 : 478.38623046875,169.61349487304688
Corners - Bot-right = 999.0,749.0 : 491.45220947265625,411.24688720703125
Corners - Bot-left = 0.0,749.0 : 162.11233520507812,411.5089416503906
现在显然点是绘制的图像是错误的 - 但选择绘制哪个意味着我已经确定了这一点。但是,我觉得奇怪的是,该框是查询图像的整个大小,转换为第二张图像的空间。我没想到盒子的尺寸和形状会缩小到与第一张图片不匹配的方式。
转换后的 x,y 对我来说没有任何意义。请问有人能解释一下吗?
查看图像 2,其中查询是一部分,目标 idx 图像给出的整体:
Initial Flann matches: 500
After Lowe's 2nd nn ratio: 21
RANSAC inliers: 17
query image dimensions x=1000, y=750
idx image dimensions x=1000, y=609
Corners - Top-left = 0.0,0.0 : -1228.55224609375,-923.1514282226562
Corners - Top-right = 999.0,0.0 : 3561.064453125,-930.8649291992188
Corners - Bot-right = 999.0,749.0 : 2768.0224609375,1934.417236328125
Corners - Bot-left = 0.0,749.0 : -699.1375732421875,2089.652587890625
这对我来说完全没有意义。 -1228?但是两个图像都只有 1000 个,并且查询完全包含在目标 idx 图像中。
最后一张图片显示了这方面的挫败感。 Image 3 - Whole-Whole 在这里,我们可以看到透视变换的角落只是遥不可及 - 它实际上比匹配的图像要小......看起来透视变换函数返回几乎随机的结果。
谁能发现我做错了什么?我是不是对透视变换有误解?
【问题讨论】:
-
你可以试试单应性 = Calib3d.findHomography(queryMatOfPoint2f, idxMatOfPoint2f, Calib3d.RANSAC, 5, mask, 2000, 0.995);? (不同的查询顺序/idx)
-
啊哈。好点子。奇怪的是我有这种方式 - 我会尝试相反的方式。
-
不确定哪个排序是正确的,但这是一个常见的错误来源:D
-
我明白为什么这会影响稍后返回的积分。快速尝试导致允许大量不匹配的项目通过。一个问题是查询对象中有多个点映射到一个点。邮票的图像或带有照明 MS 之类的词的图像可能会导致这类匹配 - 这是我试图通过单应性消除的......我将仔细检查我使用的点集,并确保我没有交换某些东西。可惜我无法将图像添加到 cmets - 所以如果这不能解决我的问题,我会更新主要问题。谢谢。
-
是的,解决了盒子问题。但是,我现在遇到了匹配质量的问题-查询中的单应性-> idx 包括虚假匹配,但是当图像确实相关时,它会得到正确的边界弓。我会发布另一个关于匹配问题的问题。非常感谢您发现如此简单的错误! (请注意,反向单应性检查实际上解决了虚假匹配问题!尽管这可能不是最好的方法。)