opencv c ++比较不同图像中的关键点位置

fak*_*unt 2 c++ opencv keypoint orb

比较两个图像时feature extraction,如何比较keypoint距离,以忽略明显不正确的距离?

我发现在比较相似的图像时,大多数情况下它可以相当准确,但有时它可以抛出完全独立的匹配.

所以我想keypoints从两个图像中查看两组图像并确定匹配keypoints是否相对位于两者的相同位置.如在其中已知keypoints在图像1上1,2和3相距很远,因此在图像2上匹配的对应关键点应该具有彼此远离彼此相当类似的距离.

我过去曾经使用RANSACminimum distance检查但只是为了一些效果,它们似乎并不像我追求的那么彻底.

(使用ORBBruteForce)

编辑

"x,y和z"更改为"1,2和3"

编辑2 - 我将尝试使用快速绘制的示例进一步解释:

说我有这个作为我的形象:

在此输入图像描述

我给它这个图像来比较:

在此输入图像描述

它是原始的裁剪和压扁版本,但显然相似.

现在,假设您已经完成了它feature detection并且它返回了这keypoints两个图像的结果:

在此输入图像描述在此输入图像描述

keypoints两个图像是在大致相同的区域,并且成比例地相同的距离相互远离.把keypoint我圈起来,我们称之为"Image 1 Keypoint 1".

在此输入图像描述

我们可以看到keypoints周围有5个.它们之间的距离和我想要获得的"Image 1 Keypoint 1",以便将它们与"Image 2 Keypoint 1"及其5个环绕keypoints在同一区域(见下文)进行比较,以便不仅仅是将a keypoint与另一个进行比较keypoint,但要比较基于位置的"已知形状"keypoints.

在此输入图像描述

-

那有意义吗?

san*_*iso 5

关键点匹配是几个维度的问题.这些维度是:

  • 空间距离,即(x,y)从不同图像中的两个关键点的位置测量的距离
  • 特征距离,即描述两个关键点看起来相似的距离.

根据您的上下文,您不希望计算相同的距离,或者您希望将两者结合起来.以下是一些用例:

  • 光流,由opencv 稀疏的Lucas-Kanade光流实现.在这种情况下,在每个帧中计算称为良好特征的关键点,然后在空间距离的基础上进行匹配.这是因为图像应该相对缓慢地改变(输入帧具有视频帧速率);
  • 图像拼接,你可以从opencv的features2d(免费或非免费)实现.在这种情况下,由于您移动相机,图像会发生根本变化.然后,您的目标就是找到稳定的点,即两个或多个图像中存在的点,无论它们的位置如何.在这种情况下,您将使用特征距离.当您拥有要在查询图像中查找的对象的模板图像时,这也适用.

为了计算特征距离,您需要计算其外观的编码版本.此操作由DescriptorExtractor类执行.然后,您可以计算描述输出之间的距离:如果两个描述之间的距离很小,则原始关键点很可能对应于同一个场景点.

计算距离时要注意使用正确的距离函数:ORB,FREAK,BRISK依赖于汉明距离,而SIFt和SURF使用更常见的L2距离.

匹配过滤

当您有单独的匹配时,您可能希望执行匹配过滤,以拒绝可能由场景模糊引起的个别匹配.想想一个源自房屋窗户角落的关键点.然后它很可能与另一个房子里的另一个窗口匹配,但这可能不是好房子或好窗口.

你有几种方法:

  • RANSAC使用当前解决方案估计执行计算匹配的一致性检查.基本上,它随机选取一些匹配,计算问题的解决方案(通常是2个图像之间的几何变换),然后计算有多少匹配符合此估计值.具有较高内数的估计获胜;
  • David Lowe在原始SIFT论文中进行了另一种过滤.他保留了两个与给定查询关键点匹配的最佳候选者,即具有最低距离(或最高相似度)的点.然后,他计算了比率similarity(query, best)/similarity(query, 2nd best).如果这个比例太低,那么第二好的也是比赛的一个很好的候选者,匹配的结果被称为含糊不清并被拒绝.

因此,在您的情况下,您应该如何做到这一点很可能取决于您的确切应用.

你的具体情况

在您的情况下,您希望开发基于相邻关键点的备用要素描述符.天空显然是这里的限制,但这里有一些我会遵循的步骤:

  1. 通过计算关键点的PCA使您的描述符旋转和缩放不变:

    // Form a matrix from KP locations in current image
    cv::Mat allKeyPointsMatrix = gatherAllKeypoints(keypoints); 
    
    // Compute PCA basis
    cv::PCA currentPCA(allKeyPointsMatrix, 2);
    
    // Reproject keypoints in new basis
    cv::Mat normalizedKeyPoints = currentPCA.project(allKeyPointsMatrix);
    
    Run Code Online (Sandbox Code Playgroud)
  2. (可选)对四叉树或kd树中的关键点进行排序,以实现更快的空间索引

  3. 为每个关键点计算一个描述符,该描述符是(例如)4或5个最接近关键点的标准化坐标中的偏移量
  4. 在查询图像中执行相同操作
  5. 根据这些新描述符匹配两个法师的关键点.