İki Görüntü Arasındaki Benzerlik Oranı

İki görüntüyü karşılaştırmak istediğinizde bunu yapmanın farklı yöntemleri vardır. En kolay yöntemlerden biriside tek tek piksellere bakarak aynı olup olmadığını kontrol etmekttir. RGB (R Kırmızı G Yeşil B Mavi) renk uzayına sahip görüntüler üç katmandan oluşmaktadır. Görüntüyü bir matris olarak ele aldığımızda RGB renk uzayındaki görüntülerin üç katmanlı olduğunu söyleyebiliriz. Siyah beyaz veya gri renk uzayına sahip görüntüler ise  tek boyutlu bir dizi olarak tanımlanabilir. Burdan sonrası ise iki matris arasındaki farkı bulmaktan başka birşey değil.

gray color space gray color space

Görüntünün 300×300 olduğunu varsayarsak elimizde 90.000 adet piksel olacak tabi iki boyutlu bir renk uzayında çalışıyorsak. Bukadar piksel sayısı 1024×768 RGB formatında bir görüntü için işlemci yükü açısından sorun teşkil edebilir ve işlem süreniz doğrudan uzar. İşlem süresi sizin için önemli ise öncelikle resmin renk uzayını değiştirebilirsiniz. Renk uzayları ve uzaylar arası dönüşüm için görüntü işleme kategorisindeki yazılara göz atabilir veya site içi arama yapabilirsiniz.

İki görüntü arasındaki farkı yüzde olarak hesaplamak isterseniz yapacağınız şey farklı olan pikselleri bir dizide toplamak ve toplam piksel sayısı ile oranlamak olacaktır. Eğer iki resim bire bir aynı ise farklı piksel sayısı sıfır olacaktır.  İki resim bir birinin kopyası değil ise (Copy Paste) farklı t sürelerinde aynı konumdan çekilmiş fotoğraflar ise bu iki fotoğrafın piksel değerlerinde ışığa veya ortama bağlı olarak pikseller arası farklılıklar olabilir bu durum sonucu etkileyeceği için görüntülerin renk uzayı değiştirilebilir veya belirli bir tolerans payı konulabilir. İki görüntü arasındaki boyut farkıda (örn. 600×480) aşağıdaki örnekte sonucu etileyecektir zira piksel sayıları aynı olmayacağı için hata ile karşılaşacaksınız.

 Örnek C#

public float Difference(Bitmap image1, Bitmap image2)
    {
        float diff = 0;
        //Birinci görüntünün yüksekliği * genişliği kadar, yani tüm pikseller
        for (int y = 0; y < image1.Height; y++)
        {
            for (int x = 0; x < image2.Width; x++)
            {    
                //Bitmap sınıfı içerisideki GetPixel metodu piksel değerini okur
                //RGB formatı referans alınmıştır, iki görüntü için aynı piksellerin mutlak farkı hesaplanır ve maksimum değeri olan 255 ile oranlanır
                diff += (float)Math.Abs(image1.GetPixel(x, y).R - image2.GetPixel(x, y).R) / 255;
                diff += (float)Math.Abs(image1.GetPixel(x, y).G - image2.GetPixel(x, y).G) / 255;
                diff += (float)Math.Abs(image1.GetPixel(x, y).B - image2.GetPixel(x, y).B) / 255;
            }
        }
        //Farkı ve toplam piksel sayısını kullanarak sonucu hesaplar
        return 100 * diff / (image1.Width * image1.Height * 3);      
    }
Console.WriteLine("Görüntüler arasındaki fark: {0} %", Difference(new Bitmap("kaynak1.jpg"), new Bitmap("kaynak2.jpg")));

 

Piksellerin değerine ulaşabiliyor ve karşılaştırabiliyorsak, iki pikselin farkını yeni bir piksele atayarak görsel olarak arasındaki farkı belirleyebiliriz. Bitmap sınıfının getpixel ve setpixel metotları olduğunu görmüştük, farkı hesaplamak yerine pikseller farklı ise bu farkı yeni bir bitmap oluşturup boyutlarınıda karşılaştırılan iki görsel ile aynı boyutlarda verebiliriz bu sayede iki görsel tamamen farklı ise tüm farkı birinci görüntüden veya ikinci görüntüden alabiliriz. Basit bir örnek yapalım. Örnekte paint ile oluşturduğum bir kısmı aynı iki adet görsel var bunları karşılaştıracak ve pikseller arasında bir fark var ise o pikseli yeni oluşturacağımız bitmap nesnesinde karşılık gelen piksele kopyalayacağız. Son olarak dosya sistemine yazdıracak ve aradaki farkı görmüş olacağız.

1 2

 

 

 

 

            Bitmap image1 = new Bitmap("1.png");
            Bitmap image2 = new Bitmap("2.png");
            Bitmap a = new Bitmap(image1.Width, image1.Height);
            //Tüm pikselleri dolaş
            for (int y = 0; y < image1.Height; y++)
            {
                for (int x = 0; x < image2.Width; x++)
                {
                    //İkisi arasında fark var ise yeni bitmap nesnesine ata
                    if (image1.GetPixel(x, y) != image2.GetPixel(x, y))
                        a.SetPixel(x, y, image2.GetPixel(x, y));
                }
            }
            a.Save("yeni.png");

Sonuç ise aşağıdaki gibi olacaktır.

yeni