使用KnnMatch返回2个图像之间的相似度

时间:2014-02-09 22:17:52

标签: c# opencv image-processing emgucv

我有来自emgu opencv包装器的以下示例

HomographyMatrix homography = null;
SURFDetector surfCPU = new SURFDetector(500,true);
        VectorOfKeyPoint modelKeyPoints;
        VectorOfKeyPoint observedKeyPoints;
        Matrix<int> indices;

        Matrix<byte> mask;
        int k = 2;
        double uniquenessThreshold = 0.9; //0.8

        //extract features from the object image
        modelKeyPoints = surfCPU.DetectKeyPointsRaw(modelImage, null);
        Matrix<float> modelDescriptors = surfCPU.ComputeDescriptorsRaw(modelImage, null, modelKeyPoints);
        modelImage.Dispose();                     


        // extract features from the observed image
        observedKeyPoints = surfCPU.DetectKeyPointsRaw(observedImage, null);
        Matrix<float> observedDescriptors = surfCPU.ComputeDescriptorsRaw(observedImage, null, observedKeyPoints);
        observedImage.Dispose();
        BruteForceMatcher<float> matcher = new BruteForceMatcher<float>(DistanceType.L2);
        matcher.Add(modelDescriptors);

        indices = new Matrix<int>(observedDescriptors.Rows, k);
        using (Matrix<float> dist = new Matrix<float>(observedDescriptors.Rows, k))
        {
            matcher.KnnMatch(observedDescriptors, indices, dist, k, null);
            mask = new Matrix<byte>(dist.Rows, 1);
            mask.SetValue(255);
            Features2DToolbox.VoteForUniqueness(dist, uniquenessThreshold, mask);
        }
        //...

应用KnnMatch后,如何获得匹配关键点的数量以及非零像素数与获得2张图像之间的相似性有什么关系?

2 个答案:

答案 0 :(得分:4)

即使邻居很远,k-NN总会找到“最近的”邻居。因此,如果您的图像具有1000个兴趣点,则它们将与另一图像中的一个兴趣点匹配,即使其他图像具有更多或更少的兴趣点。

匹配次数与2幅图像之间的相似性没有直接关联,因为匹配集包含“好”匹配(内部),但也包含许多错误匹配(异常值)。

匹配后,您应过滤匹配(通过使用VoteForUniqueness和VoteForSizeAndOrientation),然后尝试查找单应矩阵。然后,您可以计算有多少匹配验证单应性。这些匹配是内部因素,相似性与内部数量有一点相关性。

您可以在this paper中找到更详细的信息:

[Augereau,O.,Journet,N。,&amp; Domenger,J。P.(2013年2月)。半结构化文档图像匹配和识别。在DRR。]

答案 1 :(得分:1)

  1. 请参阅opencv doc http://www.opencv.org.cn/opencvdoc/2.3.2/html/modules/features2d/doc/common_interfaces_of_descriptor_matchers.html

    void DescriptorMatcher :: knnMatch(const Mat&amp; queryDescriptors,vector&gt;&amp; matches,int k,const vector&amp; masks = vector(),bool compactResult = false)

    匹配(代码中为dist) - 匹配。对于相同的查询描述符,每个匹配[i]是k或更少的匹配。 k - 如果查询描述符总共少于k个可能的匹配项,则每个查询描述符找到的最佳匹配计数或更少。

  2. 关于相似度(我不清楚这个问题),代码使用L2距离。

    BruteForceMatcher matcher = new BruteForceMatcher(DistanceType.L2);