2009-12-07 41 views
0

什麼是比較2位圖,並獲得iPhone在Unity3d(是完全不同的,1是完全一樣的0)2之間的相關性最好的方法是什麼?我使用C#,因爲文檔中說,用噓聲或UnityScript會增加應用程序的大小。位圖在iPhone(unity3d)比較法

我需要的是類似於指紋識別的方法,但沒有準確的東西。由於這是爲了在iPhone上運行,性能在這裏是一個大問題。

實施例的圖像:

alt text http://img25.imageshack.us/img25/303/294906.jpg alt text http://img138.imageshack.us/img138/842/40248741fireworkexplosi.jpg

對於那些我期望爲具有約0.5的相關因子,因爲它們是類似的,但顏色不同。有許多不同的比較尺寸,但基本的是顏色和形狀。

任何幫助將不勝感激。

+0

你找誰只是或者你想要的東西更復雜,將認識到,即使一個圖像已經相對於其他移動的相似性?他們是什麼樣的形象? – 2009-12-07 18:35:28

+0

我需要一些更復雜的是將識別的相似性。圖像是顏色的抽象圖案。謝謝。 – 2009-12-07 18:45:32

+0

任何解決方案可能都會針對您的圖片的細節以及什麼被視爲「相似」的具體細節...您可以張貼一些示例圖片嗎? – 2009-12-07 18:55:41

回答

0

要回答(有點)我自己的問題,經過幾天的谷歌搜索,我找到了this。其基本思想是要測試與偏移/旋轉,尋找一個主色等圖像。到目前爲止,這是我能找到的最好的信息,所以我會試一試。

代碼建議有看起來像這樣:「什麼分數像素是在兩個圖像相同的」

using System; 
using System.Collections.Generic; 
using System.Text; 
using System.Drawing; 
using System.Drawing.Imaging; 
using System.IO; 

namespace BitmapSimilarity 
{ 
    public interface IBitmapCompare 
    { 
     double GetSimilarity(Bitmap a, Bitmap b); 
    } 

    class BitmapCompare: IBitmapCompare 
    { 
     public struct RGBdata 
     { 
      public int r; 
      public int g; 
      public int b; 

      public int GetLargest() 
      { 
       if(r>b) 
       { 
        if(r>g) 
        { 
         return 1; 
        } 
        else 
        { 
         return 2; 
        } 
       } 
       else 
       { 
        return 3; 
       } 
      } 
     } 

     private RGBdata ProcessBitmap(Bitmap a) 
     { 
      BitmapData bmpData = a.LockBits(new Rectangle(0,0,a.Width,a.Height),ImageLockMode.ReadOnly,PixelFormat.Format24bppRgb); 
      IntPtr ptr = bmpData.Scan0; 
      RGBdata data = new RGBdata(); 

      unsafe 
      { 
       byte* p = (byte*)(void*)ptr; 
       int offset = bmpData.Stride - a.Width * 3; 
       int width = a.Width * 3; 

       for (int y = 0; y < a.Height; ++y) 
       { 
        for (int x = 0; x < width; ++x) 
        { 
         data.r += p[0];    //gets red values 
         data.g += p[1];    //gets green values 
         data.b += p[2];    //gets blue values 
         ++p; 
        } 
        p += offset; 
       } 
      } 
      a.UnlockBits(bmpData); 
      return data; 
     } 

     public double GetSimilarity(Bitmap a, Bitmap b) 
     { 
      RGBdata dataA = ProcessBitmap(a); 
      RGBdata dataB = ProcessBitmap(b); 
      double result = 0; 
      int averageA = 0; 
      int averageB = 0; 
      int maxA = 0; 
      int maxB = 0; 

      maxA = ((a.Width * 3) * a.Height); 
      maxB = ((b.Width * 3) * b.Height); 

      switch (dataA.GetLargest())   //Find dominant color to compare 
      { 
       case 1: 
        { 
         averageA = Math.Abs(dataA.r/maxA); 
         averageB = Math.Abs(dataB.r/maxB); 
         result = (averageA - averageB)/2; 
         break; 
        } 
       case 2: 
        { 
         averageA = Math.Abs(dataA.g/maxA); 
         averageB = Math.Abs(dataB.g/maxB); 
         result = (averageA - averageB)/2; 
         break; 
        } 
       case 3: 
        { 
         averageA = Math.Abs(dataA.b/maxA); 
         averageB = Math.Abs(dataB.b/maxB); 
         result = (averageA - averageB)/2; 
         break; 
        } 
      } 

      result = Math.Abs((result + 100)/100); 

      if (result > 1.0) 
      { 
       result -= 1.0; 
      } 

      return result; 
     } 
    } 

    class Program 
    { 
     static BitmapCompare SimpleCompare; 
     static Bitmap searchImage; 

     static private void Line() 
     { 
      for (int x = 0; x < Console.BufferWidth; x++) 
      { 
       Console.Write("*"); 
      } 
     } 

     static void CheckDirectory(string directory,double percentage,Bitmap sImage) 
     { 
      DirectoryInfo dir = new DirectoryInfo(directory); 
      FileInfo[] files = null; 
      try 
      { 
       files = dir.GetFiles("*.jpg"); 
      } 
      catch (DirectoryNotFoundException) 
      { 
       Console.WriteLine("Bad directory specified"); 
       return; 
      } 

      double sim = 0; 

      foreach (FileInfo f in files) 
      { 
       sim = Math.Round(SimpleCompare.GetSimilarity(sImage, new Bitmap(f.FullName)),3); 
       if (sim >= percentage) 
       { 
        Console.WriteLine(f.Name); 
        Console.WriteLine("Match of: {0}", sim); 
        Line(); 
       } 
      } 
     } 

     static void Main(string[] args) 
     { 
      SimpleCompare = new BitmapCompare(); 
      Console.Write("Enter path to search image: "); 
      try 
      { 
       searchImage = new Bitmap(Console.ReadLine()); 
      } 
      catch (ArgumentException) 
      { 
       Console.WriteLine("Bad file"); 
       return; 
      } 

      Console.Write("Enter directory to scan: "); 
      string dir = Console.ReadLine(); 
      Line(); 
      CheckDirectory(dir, 0.95 , searchImage);  //Display only images that match by 95% 
     } 
    } 
} 
+0

這個例子有時會給出錯誤的結果。 – fyasar 2010-01-29 11:07:12