2012-08-27 77 views
1

因此,在業餘時間,我喜歡嘗試通過計算機視覺技術自動化各種遊戲。通常,使用濾鏡和像素檢測的模板匹配對我來說工作得很好。不過,我最近決定嘗試使用特徵匹配來瀏覽關卡。我想要的是保存整個探索地圖的過濾圖像。 FullMapEMGU中的衝浪特徵檢測/匹配問題2.4

然後到小地圖從每隔幾秒鐘後,畫面複製並以同樣的方式進行過濾,並使用衝浪匹配到我的全地圖,應該有希望給我一個玩家當前位置(本場比賽的中心將是玩家在地圖上)。按預期這個工作的一個很好的例子是以下(滿地圖找到的匹配在左邊,右邊是迷你地圖圖像。 GoodMatch

我所遇到的麻煩是在EMGU庫衝浪匹配似乎找到了不正確的匹配在 BadMatch BadMatch2

有時候很多情況下,它不是絕對的壞象下面這樣: WonkyMatch

我有種看到最新發生的是,它找到更好的匹配在不同位置的關鍵點因爲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); 
    } 

回答

1

你有一個特定的場景,在這個場景中你周圍都有黑色區域,它們圍繞着提取的關鍵點。 當涉及到特徵匹配時,請記住它在對應於提取的關鍵點的描述符之間發生。

SURF描述符描述了一個補丁,而不是一個關鍵點,並且在您的場景中可能會導致您的匹配性能較差。

[編輯]

分析場景的可能候選方法是一種由上一個部分輪廓匹配。我認爲你可以發現它已經在opencv開箱即可使用,所以我可以建議你一個好的論文「 Donoser的高效部分形狀匹配」,你可以從citeseerx中抓取並且很容易實現。

+1

你會推薦我用什麼方法來實現我想要完成的目標? – OPcorki

+0

謝謝,看起來我有一些閱讀要做! – OPcorki

+0

不客氣。我可以爲您提供另一種類似的方法,該方法基於名爲史密斯沃特曼的本地比對算法(我在大學時期將其應用於序列蛋白比對中)。以下是該論文的鏈接:http://rogerioferis.com/publications/FerisNordia08.pdf –