2012-12-01 63 views
10

我正在嘗試構建解決難題的應用程序(試圖開發圖算法),並且我不想一直手動輸入樣本輸入。在另一個圖像中查找圖像

編輯:我並沒有試圖建立一個遊戲。我試圖建立一個代理玩遊戲「SpellSeeker」

說我有一個圖像(見附件)在屏幕上的數字,我知道箱子的位置,我有確切的這些數字的圖像。我想要做的只是告訴哪個圖像(數字)在相應的盒子上。

Numbers http://i46.tinypic.com/3089vyt.jpg

所以我想我需要實現

bool isImageInsideImage(Bitmap numberImage,Bitmap Portion_Of_ScreenCap)或類似的東西。

我已經試過是(使用AForge庫)

public static bool Contains(this Bitmap template, Bitmap bmp) 
{ 
    const Int32 divisor = 4; 
    const Int32 epsilon = 10; 

    ExhaustiveTemplateMatching etm = new ExhaustiveTemplateMatching(0.9f); 

    TemplateMatch[] tm = etm.ProcessImage(
     new ResizeNearestNeighbor(template.Width/divisor, template.Height/divisor).Apply(template), 
     new ResizeNearestNeighbor(bmp.Width/divisor, bmp.Height/divisor).Apply(bmp) 
     ); 

    if (tm.Length == 1) 
    { 
     Rectangle tempRect = tm[0].Rectangle; 

     if (Math.Abs(bmp.Width/divisor - tempRect.Width) < epsilon 
      && 
      Math.Abs(bmp.Height/divisor - tempRect.Height) < epsilon) 
     { 
      return true; 
     } 
    } 

    return false; 
} 

但對於這個圖像中的黑點搜索時返回false。

我該如何執行此操作?

+0

一些數獨或井字遊戲? – bonCodigo

+0

你見過[類似地](http://stackoverflow.com/questions/2472467/how-to-find-one-image-inside-of-another)上的其他問題嗎? – bonCodigo

+0

這是一款名爲「spellseeker」的遊戲。但這並不重要,我只是想構建算法來解決這個問題。是的,其實我在其他問題中發現了這個解決方案,但他們沒有幫助我。原諒我的懶惰,但我真的認爲這應該有一個更簡單的方法:) – marvin

回答

5

我回答我的問題,因爲我已經找到了解決辦法:

this制定了我:

System.Drawing.Bitmap sourceImage = (Bitmap)Bitmap.FromFile(@"C:\SavedBMPs\1.jpg"); 
      System.Drawing.Bitmap template = (Bitmap)Bitmap.FromFile(@"C:\SavedBMPs\2.jpg"); 
      // create template matching algorithm's instance 
      // (set similarity threshold to 92.5%) 

      ExhaustiveTemplateMatching tm = new ExhaustiveTemplateMatching(0.921f); 
       // find all matchings with specified above similarity 

       TemplateMatch[] matchings = tm.ProcessImage(sourceImage, template); 
       // highlight found matchings 

      BitmapData data = sourceImage.LockBits(
       new Rectangle(0, 0, sourceImage.Width, sourceImage.Height), 
       ImageLockMode.ReadWrite, sourceImage.PixelFormat); 
      foreach (TemplateMatch m in matchings) 
      { 

        Drawing.Rectangle(data, m.Rectangle, Color.White); 

       MessageBox.Show(m.Rectangle.Location.ToString()); 
       // do something else with matching 
      } 
      sourceImage.UnlockBits(data); 

唯一的問題是它爲所述遊戲找到所有(58)盒子。但是將0.921f的值改爲0.98使得它完美,即它只找到指定數字的圖像(模板)

編輯:我實際上必須爲不同的圖片輸入不同的相似性閾值。我發現通過嘗試優化值,最後我有一個功能,如

float getSimilarityThreshold(int number) 
1

更好的方法是構建一個自定義類,它保存所需的所有信息而不是依賴圖像本身。

例如:

public class MyTile 
{ 
    public Bitmap TileBitmap; 
    public Location CurrentPosition; 
    public int Value; 
} 

這樣你可以從Value場「走動」的瓷磚類和閱讀的價值,而不是圖像分析。您只需將課堂上持有的任何圖像繪製到當前所持的位置即可。

private list<MyTile> MyTiles = new list<MyTile>(); 

根據需要擴展類(記得要處理這些圖像時,他們不再需要):

您瓷磚可以在一個陣列等保持。

,如果你真的,看是否存在圖像內的圖像,你可以看看這個擴展我寫的另一篇文章(雖然在VB代碼):
Vb.Net Check If Image Existing In Another Image

+0

感謝您的回答。我已經有一個類似這樣的課程。我有一個帶有值的節點類(在文本框中)和一個具有節點數組的Tile類。但初始化所有節點的問題仍然存在。我可以將它們輸入到文本框中,但它仍然意味着我必須手動輸入60個數字,運行時間爲2秒。所以我正在尋找一種方法來使用打印屏幕圖像來初始化它們。 – marvin