【问题标题】:Surf Feature detection/matching issues in EMGU 2.4EMGU 2.4 中的冲浪特征检测/匹配问题
【发布时间】:2012-08-21 14:01:42
【问题描述】:

所以在业余时间,我喜欢尝试通过计算机视觉技术来自动化各种游戏。通常,与过滤器和像素检测匹配的模板对我来说效果很好。然而,我最近决定尝试通过使用特征匹配来浏览一个关卡。我的意图是保存整个探索地图的过滤图像。

然后每隔几秒从屏幕上复制小地图并以相同的方式对其进行过滤,并使用 Surf 将其与我的完整地图匹配,这有望为我提供玩家当前位置(比赛中心将是玩家所在的位置)在地图上)。下面是按预期工作的一个很好的例子(左侧找到匹配的完整地图,右侧是迷你地图图像。

我遇到的问题是 EMGU 库中的 Surf Matching 在许多情况下似乎找到了不正确的匹配项。

有时它并不完全糟糕,如下所示:

我可以看到发生了什么,因为 Surf 应该是比例不变的,因此它可以更好地匹配地图上不同位置的关键点。我对 EMGU 库或 Surf 的了解不够,无法对其进行限制,使其只接受像最初的好匹配这样的匹配,要么丢弃这些糟糕的匹配,要么对其进行调整,让那些不稳定的匹配变成好的匹配。

我正在使用新的 2.4 EMGU 代码库,我的 SURF 匹配代码如下。我真的很想明白这一点,以便它只返回始终相同大小的匹配(正常小地图大小与完整地图上的大小的比例),这样我就不会得到一些疯狂的形状匹配.

public Point MinimapMatch(Bitmap Minimap, Bitmap FullMap)
    {
        Image<Gray, Byte> modelImage = new Image<Gray, byte>(Minimap);
        Image<Gray, Byte> observedImage = new Image<Gray, byte>(FullMap);     
        HomographyMatrix homography = null;

        SURFDetector surfCPU = new SURFDetector(100, false);
        VectorOfKeyPoint modelKeyPoints;
        VectorOfKeyPoint observedKeyPoints;
        Matrix<int> indices;

        Matrix<byte> mask;
        int k = 6;
        double uniquenessThreshold = 0.9;
        try
        {
            //extract features from the object image
            modelKeyPoints = surfCPU.DetectKeyPointsRaw(modelImage, null);
            Matrix<float> modelDescriptors = surfCPU.ComputeDescriptorsRaw(modelImage, null, modelKeyPoints);

            // extract features from the observed image
            observedKeyPoints = surfCPU.DetectKeyPointsRaw(observedImage, null);
            Matrix<float> observedDescriptors = surfCPU.ComputeDescriptorsRaw(observedImage, null, observedKeyPoints);
            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);
            }

            int nonZeroCount = CvInvoke.cvCountNonZero(mask);
            if (nonZeroCount >= 4)
            {
                nonZeroCount = Features2DToolbox.VoteForSizeAndOrientation(modelKeyPoints, observedKeyPoints, indices, mask, 1.5, 20);
                if (nonZeroCount >= 4)
                    homography = Features2DToolbox.GetHomographyMatrixFromMatchedFeatures(modelKeyPoints, observedKeyPoints, indices, mask, 2);
            }

            if (homography != null)
            {  //draw a rectangle along the projected model
                Rectangle rect = modelImage.ROI;
                PointF[] pts = new PointF[] { 
                new PointF(rect.Left, rect.Bottom),
                new PointF(rect.Right, rect.Bottom),
                new PointF(rect.Right, rect.Top),
                new PointF(rect.Left, rect.Top)};
                homography.ProjectPoints(pts);
                Array.ConvertAll<PointF, Point>(pts, Point.Round);

                Image<Bgr, Byte> result = Features2DToolbox.DrawMatches(modelImage, modelKeyPoints, observedImage, observedKeyPoints, indices, new Bgr(255, 255, 255), new Bgr(255, 255, 255), mask, Features2DToolbox.KeypointDrawType.DEFAULT);
                result.DrawPolyline(Array.ConvertAll<PointF, Point>(pts, Point.Round), true, new Bgr(Color.Red), 5);                  

                return new Point(Convert.ToInt32((pts[0].X + pts[1].X) / 2), Convert.ToInt32((pts[0].Y + pts[3].Y) / 2));
            }


        }
        catch (Exception e)
        {
            return new Point(0, 0);
        }


     return new Point(0,0);
  }

【问题讨论】:

    标签: c# image-processing opencv emgucv surf


    【解决方案1】:

    您有一个特定的场景,其中提取的关键点周围都有黑色区域。 当涉及到特征匹配时,请记住它发生在与提取的关键点相对应的描述符之间。

    SURF 描述符描述的是一个补丁而不是单个关键点,在您的场景中,这可能是您匹配性能不佳的原因。

    [编辑]

    分析您的场景,一种可能的候选方法是一种包含部分轮廓匹配的方法。我不认为你会发现它已经在 opencv 中实现了开箱即用,所以我可以建议你写一篇好论文“ Donoser 的“外部轮廓的高效部分形状匹配”,您可以从 citeseerx 中获取并非常容易地实现。

    【讨论】:

    • 你会推荐我使用什么方法来完成我想要完成的任务?
    • 不客气。我可以为您提供另一种类似的方法,它基于名为 Smith Waterman 的局部比对算法(我在大学期间将其用于序列蛋白质比对)。这是论文的链接:rogerioferis.com/publications/FerisNordia08.pdf
    猜你喜欢
    • 2015-01-30
    • 2014-04-04
    • 2012-06-03
    • 1970-01-01
    • 2011-09-04
    • 1970-01-01
    • 2018-12-10
    • 2018-02-16
    • 1970-01-01
    相关资源
    最近更新 更多