Pergunta

Qual seria o melhor método para comparar 2 bitmaps e obter a correlação entre a 2 (0 sendo completamente diferente e 1 sendo exatamente o mesmo) em Unity3D no iPhone? Eu estou usando C # desde documentação diz que o uso de Boo ou UnityScript irá aumentar o tamanho do aplicativo.

O que eu preciso é algo semelhante aos métodos de identificação de impressões digitais, mas não tão preciso. Uma vez que este se destina a ser executado no desempenho iPhone é um grande problema aqui.

imagens Exemplo:

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

Para aqueles que seria de esperar para ter um fator de correlação de cerca de 0,5, uma vez que são semelhantes, mas diferem na cor. Há um número de diferentes dimensões de comparação, mas os básicos são de cor e forma.

Qualquer ajuda será muito apreciada.

Foi útil?

Solução

Para responder (tipo de) minha própria pergunta, depois de dias de googling, eu encontrei este . A idéia básica é a de teste para imagens com deslocamento / rotação, a busca de uma cor dominante e assim por diante. Até agora, esta é a melhor informação que eu poderia encontrar, por isso vou dar-lhe uma tentativa.

O código sugeriu que se parece com isso:

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%
        }
    }
}
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top