11 Kasım 2013 Pazartesi

Resim işleme - Komşu pikseller yardımı ile kenar bulma algoritması

Resmin Kenarlarını Bulma Yöntemi

Merhabalar, bu gün projelerinizde kullanabileceğiniz bir kenar bulma metodunu anlatacağım.

Metodun Çalışma Mantığı

Siyah beyaz bir resimde kenar bulma işlemi piksellerdeki ani parlaklık değişimlerinden yola çıkarak yapılır. Beyaz bir arkaplan üzerinde siyah bir kare resmi hayal edelim. Karenin sol kenarının sol tarafındaki piksel beyaz, bu pikselin sağ tarafındaki piksel ise siyah olacak. Böyle bir durumda bu pikseli bir kenar olarak işaretleyebiliriz.


Resimde yukarıda anlattığımız metod ile kenarları belirlenmiş ve kenar pikselleri kırmızı olarak işaretlenmiş kareyi görüyorsunuz.


Renkli resimlerde de parlaklık farkı yerine piksellerin komşularından herhangi veya her kanaldaki (R,G,B renk kanallarından bahsediyorum) renk farklılığından yola çıkarak kenar algılama işlemini gerçekleştirebiliriz.

Matematiksel Kısım (basitleştirilmiş halde)


Kenarları tespit etmek için piksellerin komşu piksellere göre farklılık seviyesini kullanıyoruz.  (x,y) şeklinde koordinatları verilmiş olan pikselimizin parlaklığına A(x,y) dersek değişimi hesaplamak için formülümüz şöyle olur.;








Formülde pikselin dört bir tarafındaki komşularının parlaklığını baz alarak pikselin kenar olup olmadığına karar veriyoruz (x+1,y pikselin sağ komşusu, x-1,y  pikselin sol komşusu x,y+1  pikselin  alt komşusu, x,y-1  pikselin üst komşusu).


Ortaya çıkan G değeri, değişim derecemiz oluyor. Bu derece bizim belirlediğimiz belirli bir eşikten yüksekteyse söz konusu pikseli kenar olarak işaretliyoruz. Bu eşik resmin netliğine göre el ile ayarlandığında en sağlıklı sonuç elde ediliyor.


Programlama Kısmı


Aşağıda C# dilinde yazılmış, resmin RGB kanallarından red (kırmızı) kanalı üzerinde yukarıdaki yöntemi kullanarak çalışan bir fonksiyon var. Kodda eşiği 14 değerine sabitledim fakat ihtiyacınıza göre değiştirebilirsiniz.

private 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);
int dx = cr.R - cl.R;
int dy = cd.R - cu.R;
double power = Math.Sqrt(dx * dx / 4 + dy * dy / 4);
if (power > 14)
ret.SetPixel(i, j, Color.Yellow);
else
ret.SetPixel(i, j, Color.Black);
}
}
  return ret;
}

Sonuç 


Bir sonraki yazımda daha gelişmiş bir algoritma kullanarak daha etkili sonuçlar elde edeceğiz :) beklemede kalın.