代码之家  ›  专栏  ›  技术社区  ›  Daniel Rodriguez

iPhone上的位图比较方法(unity3d)

  •  0
  • Daniel Rodriguez  · 技术社区  · 15 年前

    我需要的是类似于指纹识别方法的东西,但不是那么准确。因为这是为了在iPhone上运行,所以性能在这里是一个大问题。

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

    对于那些我希望有一个大约0.5的相关系数,因为它们相似但颜色不同。比较有许多不同的维度,但基本的维度是颜色和形状。

    1 回复  |  直到 15 年前
        1
  •  0
  •   Daniel Rodriguez    15 年前

    为了回答我自己的问题,在谷歌搜索了几天之后,我发现 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%
            }
        }
    }