|
C# ile Temel Görüntü İşleme Yöntemleri |
|
Gönderiliyor lütfen bekleyin... |
|
|
Bu
çalışmada Visual Studio C# .NET’de görüntü işlemenin
nasıl yapıldığı temel olarak ele
alınmaktadır. Çalışmamızı Windows uygulaması
olan formlarda gerçekleştireceğiz. Bunun için görüntülerimizi
göstermek amacıyla bir form aleti olan PictureBox kullanacağız. Yaptığımız
işlem en basit anlamıyla açılan resmin piksellerine teker teker
erişip istediğimiz işlemi piksellere uygulamaktır. Biz
burada üç farklı görüntü işleme yönteminin C# programlama dili ile
nasıl yapılacağını göstermeye çalıştık.
İlk yöntemde resmimizin rengini tersine çevirme ,ikinci yöntemde resmimize
kabartma etkisi uygulama, üçüncü yöntemde ise resmi siyah-beyaz yani gri
tonlara çeviren işlemleri gerçekleştirdik. Bu etkiler hakkında
ayrıntılar sırasıyla ele alınacaktır. Her bir
yöntem bir düğme olayıyla tetiklenmektedir. O halde ilgili
kodları her bir farklı düğmenin basma(click) olayının
içerisine yazacağız. Ayrıca gerçekleşen işlemin hangi
aşamada olduğunu görmek için işlem çubuğu (progressBar)
eklenmiştir.
Etkilerimize
geçmeden önce birkaç gerekli terimden bahsetmek gerekiyor. Biz,
aldığımız görüntüleri, pictureBox içinde gösterilen
resmi elde edip onunla işlem yapmamızı sağlayan System.Drawing
isim uzayının içinde Image sınıfı ve piksel
verisine ulaşmak için yine System.Drawing isim uzayının
içinde Bitmap sınıflarını kullanmaktayız. Bitmap
sınıfında tanımladığımız bir resmin
piksel verilerini okuduktan sonra bu pikseller üzerinde işlem yapabilmek
için Bitmap sınıfına ait aşağıdaki temel metotları
kullanmaktayız.
GetPixel(x,y)
Bu metot x,y noktasında bulunan pikselin rengini verir.
SetPixel(x,y)
Bu metot kullanılarak x,y noktasındaki pikselin rengi
değiştirilebilir.
|
Şunu
belirtmek gerekir ki Bitmap sınıfı Image
sınıfından türemiştir ayrıca Image sınıfından
türemiş Imaging.Metafile sınıfa da mevcuttur. Vektör türü
grafikler (wmf, emf vb.) için Imaging.Metafile sınıfı,
Bitmap türü grafikler (bmp, jpeg, gif vb.) için de Bitmap
sınıfı kullanılır. Image
sınıfına ait birçok özellik ve metotlar vardır. Biz burada
bu özellik ve metotların hepsine değinmeyeceğiz. Bunlara
yardım belgelerinden erişebilir ve neler olduğunu
öğrenebilirsiniz. Örneğin Image sınıfının
metotları sayesinde ilgili resmimiz Clone() metoduyla
kopyalayabilir, RotateFlip(yön) ile döndürebilir, PhysicalDimensions
ile orijinal boyutunu öğrenebilir, PixelFormat ile resmin piksel
formatını öğrenebilir, HorizontalResolution ve VerticalResolution
ile bir resmin yatay ve dikey çözünürlüğünü bu iki özellikle
öğrenebiliriz (Çözünürlük bilgileri dpi –dot per inch – cinsindendir).
Şimdi
gelelim resim etkilerimizi nasıl oluşturduğumuza;
Öncelikle
formumuzun içine iki tane pictureBox ve üç tane düğme
yerleştirelim çünkü daha önceden de belirttiğim gibi görüntü
etkilerimiz düğme olayıyla tetiklenecektir. Şimdi en önemli
kısma geldik; resmimiz iki boyutlu olup piksellerden
oluşmaktadır piksellere erişip istenen işlemi uygulamak
için ise iki tane for döngüsü kullanmalıyız. Yani bütün
pikselleri yatay ve dikey olarak taramalıyız.
Bir resmin renklerini tersine alma
Aşağıdaki
ilk etkimizin kodları vardır. İlk olarak pictureBox içine bir
resim açmadığımızda ve işlem yürütmeye
çalıştığımızda karşımıza bir
uyarı mesajı vermesi sağlanmıştır. Burada Color
sınıfından bir referans renk değişkeni belirliyoruz.
pictureBox içindeki resmin piksellerine erişmek için Bitmap
sınıfında yeni bir sınıf tanımlıyoruz ve
progressBar’ın en yüksek çizgisi işlemin bittiğini göstermesi
için en son işlenecek pikselle belirlenmiştir. GetPixel ile o
anki döngümüzün pikseline erişip renk bileşenini okumaktayız. Color.FromArgb
dört bileşenli (alpha , red, gren, blue) 8-bitlik renk bilgisine
erişmemizi sağlar. Burada renkleralfa kanalı hariç DEĞİL(NOT)
lenerek tersi alınmaktadır. Tersi alınan bu renk bilgisi
asıl resmimizin piksel değerleriyle Setpixel komutuyla
değiştirilmektedir. Şimdi kodu inceleyelim. Gerekli
açıklamalar kodda yer almaktadır. Kodu kopyala
yapıştır yaparak sizde çalışıp
çalışmadığını deneyebilirsiniz ama tavsiyem kendi
yazmanızdır.
if(pictureBox1.Image==null)
{
MessageBox.Show("Önce bir resim Seçin");
}
else
{
progressBar1.Visible=true;//progress(işlem) çubuğu koyalım
int i,j;
Color r;
Bitmap bmp=new Bitmap(pictureBox1.Image);
progressBar1.Maximum=bmp.Width*bmp.Height;
for(i=0;i<=bmp.Width-1;i++)
{
for(j=0;j<=bmp.Height-1;j++)
{
r=bmp.GetPixel(i,j);//i,j noktasının rengini öğren
//alfa kanalı hariç diğer kanalların tersini al
r=Color.FromArgb(r.A,(byte)~r.R,(byte)~r.G,(byte)~r.B);
bmp.SetPixel(i,j,r);//aynı noktaya tekrar koy
if((i%10)==0)//her on satırda bir göstergeyi güncelle
{
progressBar1.Value=i*bmp.Height+j;
Application.DoEvents();
}
}
}
pictureBox2.Image=bmp;
progressBar1.Visible=false; //işlem bittiğinde çubuklar görünmez olsun
}//else sonu |
Bir resme kabartma (emboss) etkisi yaratmak
Kabartma
(emboss) etkisi resimdeki pikselin ve bir sonraki pikselin renk farkına
128 eklenmesiyle elde edilir. Bu iki pikselin renklerini öğrendikten sonra
renklerin farkını alıp bu sonuca 128 ekleyerek yeni rengi
oluşturursak kabartma etkisi vermiş oluruz. Ekleme işleminden
sonra sekiz bitlik renk bilgisini aşmaması için 255 e eşikleme
yapıyoruz (28=256 seviye)
if(pictureBox1.Image==null)
{
MessageBox.Show("Önce bir resim Seçin");
}
else
{
progressBar1.Visible=true;
int i,j;
Color renk1,renk2,renk3;
Bitmap bmp=new Bitmap(pictureBox1.Image);
int r,g,b;
progressBar1.Maximum=bmp.Width*bmp.Height;
for(i=0;i<=bmp.Width-2;i++)
{
for(j=0;j<=bmp.Height-2;j++)
{
renk1=bmp.GetPixel(i,j);//i,j noktasının rengini öğren
renk2=bmp.GetPixel(i+1,j+1);//sonraki noktanın rengini öğren
r=Math.Abs((int)(renk1.R)-renk2.R)+128;
if(r>255)
r=255;
g=Math.Abs((int)(renk1.G)-renk2.G)+128;
if(g>255)
g=255;
b=Math.Abs((int)(renk1.B)-renk2.B)+128;
if(b>255)
b=255;
renk3=Color.FromArgb(r,g,b);
bmp.SetPixel(i,j,renk3);
if((i%10)==0)//her on satırda bir göstergeyi güncelle
{
progressBar1.Value=i*bmp.Height+j;
Application.DoEvents();
}
}
}
pictureBox2.Image=bmp;
progressBar1.Visible=false;
}//else sonu |
Bir resmi siyah beyaz yapma (gri tonlara çevirme)
Bu
etkimizdeki temel mantık her bir renk bileşenlerinin aritmetik
ortalamasını alıp çıkan sonucu her üç renk bileşenine
atamak olacaktır. Diğer işlemeler önceki etkilerimiz ile
aynıdır.
if(pictureBox1.Image==null)
{
MessageBox.Show("Önce bir resim Seçin");
}
else
{
progressBar1.Visible=true;
int i,j;
Color renk;//Color sınıfından bir renk nesne tanımlıyoruz.
Bitmap bmp=new Bitmap(pictureBox1.Image);
//int r,g,b;
progressBar1.Maximum=bmp.Width*bmp.Height;//İşlem çubuğunun maksimim
olduğu yer for döngüsünün sonundaki piksel değerine erişmemiz
durumundadır.
for(i=0;i<=bmp.Width-1;i++)//dikey olarak görüntümüzü tarıyoruz.
{
for(j=0;j<=bmp.Height-1;j++)//yatay olarak görüntümüzü tarıyoruz.
{
renk=bmp.GetPixel(i,j);
renk=Color.FromArgb((byte)((renk.R+renk.G+renk.B)/3),(byte)((renk.R+renk.G+renk.B)/3),(byte)((renk.R+renk.G+renk.B)/3));
bmp.SetPixel(i,j,renk);
if((i%10)==0)//her on satırda bir göstergeyi güncelle
{
progressBar1.Value=i*bmp.Height+j;
Application.DoEvents();
}
}
}
pictureBox2.Image=bmp;
progressBar1.Visible=false;
}//else sonu |
Dosyadan resim açmak:
Aşağıdaki
kodu bir düğme olayına eklersek belirtilen dosya biçimlerinde
dosyaları açabiliriz. Yeni bir dosya açmak istersek işlem
yapmış olduğumuz ikinci pictureBox daki resim
sıfırlanacaktır.
openFileDialog1.Filter="Resim
Dosyaları|"+"*.bmp;*.jpg;*.gif;*.wmf;*.tif;*.png";
if(openFileDialog1.ShowDialog()==DialogResult.OK)
{
pictureBox2.Image=null;
pictureBox1.Image=Image.FromFile(openFileDialog1.FileName);
} |
Ayrıca
belirtmem gereken bir şeyde pictureBox’ların özellik
kısımlarından SizeMode özelliğini(properties) StretchImage
yaparak resmi pictureBox boyutuna sığdırabilirsiniz. Aksi
takdirde resmin sadece bir kısmını görürüz.
Kaynaklar:
1.Kocaeli Üniversitesi İşaret ve
Görüntü İşleme Laboratuvarı
Hazırlayan:
Yılmaz Ürgün
Kocaeli Üniversitesi Elektronik ve Haberleşme
Mühendisliği
Makale:
C# ile Temel Görüntü İşleme Yöntemleri C#, Visual C# ve .NET Yılmaz Ürgün
|
|
|
-
-
Eklenen Son 10
-
Bu Konuda Geçmiş 10
Bu Konuda Yazılmış Yazılmış 10 Makale Yükleniyor
Son Eklenen 10 Makale Yükleniyor
Bu Konuda Yazılmış Geçmiş Makaleler Yükleniyor
|
|