8 Aralık 2013 Pazar

Resim İşleme - Şablon tabanlı algoritmalar

Resim İşleme - Şablon tabanlı algoritmalar


Resmin kenarlarını tespit ederken belirli şablonlar kullanarak daha sağlıklı sonuçlar elde edebiliriz. Bu yazımızda Sobel kenar bulma algoritmasını kullanacağız. Bu algoritma da bir önceki yazımızda kullandığımız yöntemle aynı mantıkta çalışıyor fakat daha iyi sonuçlar vermesi için biraz değiştirilmiş.

Sobel şablonu aşağıdaki gibi tanımlanmış:





Üzerinde çalışılan resmin her pikseli için iki şablon da pikselin etrafındaki 3x3'lük bir alana uygulanıyor. Çevredeki piksellerin parlaklık değerleri matriste karşılık gelen değerlerle çarpılıp toplanıyor.







Formülde T, ya  Sx (x ekseni için) ya da Sy (y ekseni için) oluyor. Sonrasında da lx ve ly'nin mutlak değerleri toplanıyor.






En son olarak da l belirlenen eşik ile karşılaştırılıp büyük çıkarsa kenar olarak işaretleniyor.



Bunun gibi bir başka şablon metododu da Kirsch metodu, o da bununla aynı mantıkla çalışmakla beraber 2 yerine 8 adet şablon kullanıyor: sol-sağ, aşağı-yukarı, sol üst-sol alt, sağ üst-sağ alt. Resmin her pikseli için 8 şablon uygulanıyor ve aralarından en yüksek olanı eşik değeri ile karşılaştırılıyor.

Kod:

C# dilinde örnek kod:


           public Bitmap sinirbul(Bitmap resim)
            {
                Bitmap ret = new Bitmap(resim.Width, resim.Height);
                for (int i = 1; i < resim.Width - 1; i++)
                {
                    for (int j = 1; j < resim.Height - 1; j++)
                    {
                        Color cr = resim.GetPixel(i + 1, j);
                        Color cl = resim.GetPixel(i - 1, j);
                        Color cu = resim.GetPixel(i, j - 1);
                        Color cd = resim.GetPixel(i, j + 1);
                        Color cld = resim.GetPixel(i - 1, j + 1);
                        Color clu = resim.GetPixel(i - 1, j - 1);
                        Color crd = resim.GetPixel(i + 1, j + 1);
                        Color cru = resim.GetPixel(i + 1, j - 1);
                        int power = getMaxD(cr.R, cl.R, cu.R, cd.R, cld.R, clu.R, cru.R, crd.R);
                        if (power > 50)
                            ret.SetPixel(i, j, Color.Yellow);
                        else
                            ret.SetPixel(i, j, Color.Black);
                    }
                }
                return ret;
            }
            private int getD(int cr, int cl, int cu, int cd, int cld, int clu, int cru, int crd, int[,] matrix)
            {
                return Math.Abs(matrix[0, 0] * clu + matrix[0, 1] * cu + matrix[0, 2] * cru
                   + matrix[1, 0] * cl + matrix[1, 2] * cr
                      + matrix[2, 0] * cld + matrix[2, 1] * cd + matrix[2, 2] * crd);
            }
            private int getMaxD(int cr, int cl, int cu, int cd, int cld, int clu, int cru, int crd)
            {
                int max = int.MinValue;
                for (int i = 0; i < templates.Count; i++)
                {
                    int newVal = getD(cr, cl, cu, cd, cld, clu, cru, crd, templates[i]);
                    if (newVal > max)
                        max = newVal;
                }
                return max;
            }

        
        
        
        private List<int[,]> templates = new List<int[,]> 
{
   new int[,] {{ -3, -3, 5 }, { -3, 0, 5 }, { -3, -3, 5 } },
   new int[,] {{ -3, 5, 5 }, { -3, 0, 5 }, { -3, -3, -3 } },
   new int[,] {{ 5, 5, 5 }, { -3, 0, -3 }, { -3, -3, -3 } },
   new int[,] {{ 5, 5, -3 }, { 5, 0, -3 }, { -3, -3, -3 } },
   new int[,] {{ 5, -3, -3 }, { 5, 0, -3 }, { 5, -3, -3 } },
   new int[,] {{ -3, -3, -3 }, { 5, 0, -3 }, { 5, 5, -3 } },
   new int[,] {{ -3, -3, -3 }, { -3, 0, -3 }, { 5, 5, 5 } },
   new int[,] {{ -3, -3, -3 }, { -3, 0, 5 }, { -3, 5, 5 } }
};

Hazır program : http://sdrv.ms/1bQoZxX

Sonuç:




Bir başka yazıda görüşmek üzere.