Görüntü İşleme (C#) - Uygulama

Eylül 4, 2009 21:35 tarihinde farukterzioglu tarafndan eklenmistir.

gi Daha önce burada ve burada anlatılan c# ile görüntü işlemeyi ufak bir uygulama üzerinde anlatmak istedim. Daha önce kod yapısından ve bazı temel işlemlerden bahsetmiştim. Şimdi bu işlemleri uygulayabilmek için basitçe; yeni resmin alınabildiği, seçilen işlemin uygulanıp yeni resmin kaydedilebildiği, bir adımlık geri alma özeliğininb bulunduğu ufak bir çalışma görüntü işlemeye giriş açısından yararlı olur diye düşündüm. Yapılan uygulamanın arayüzü ;

Proje içerisinde de kod bloklarına bazı açıklamalar eklediğim uygulamayı buradan (Görüntü İşler.rar (43,74 kb) indirebilirsiniz.

Uygulamadan bahsedersek, resim al düğmesi ile resim seçildikten sonra combobox tan bir işlem seçip işle düğmesine basarak yeni resim elde edilir ve resim kutusuna yansıtılır. Kodları açıklarsak ;

        private void button2_Click(object sender, EventArgs e)
        {
            if (Resim != null)
            {
                tut = yeniResim;
                switch (comboBox1.SelectedIndex)
                {
                    case 0:
                        {
                            if (checkBox1.Checked)
                            {
                                İşlem.siyafbeyaz(yeniResim);
                            }
                            else
                            {
                                yeniResim = İşlem.siyafbeyaz((Bitmap)Resim.Clone());                               
                            }
                           
                            break;
                        }
                    case 1:
                        {
                            if (checkBox1.Checked)
                            {
                                İşlem.tersi(yeniResim);
                            }
                            else
                            {
                                yeniResim = İşlem.tersi((Bitmap)Resim.Clone());
                            }
                            break;
                        }
                }

                pictureBox2.Image = yeniResim;
            }
        }

     Yukarıda kod bloğunda, ilk olarak bir resim seçilmişmi kontrol edilir. Daha sonra, geri alma fonksiyonu ile işlenecek resim tutulur. switch-case yapısı ile seçilen işlem kontrol edilip, işlemin asıl resimemi yoksa işlenmiş resimemi uygulanacağı kontrol edilir. "İşlem.siyafbeyaz(yeniResim);" şeklinde bir kullanım ile parametre olarak gönderilen resimim asılı değiştirilir.  Eğer asıl resimde değişiklik yapmak istemezsek, "İşlem.siyafbeyaz((Bitmap)Resim.Clone());" şeklinde resimin kopyasını göndermeliyiz.

     Uygulanacak işlemlerin kodları "İşlem.cs" isimli bir sınıfta tutuluyor. Bu sınıf içindeki kodların yapısını daha önce anlatmıştım. Bu uygulamada şimdilik 'siyah-beyaz' ve 'tersi' işlemleri var.

     Giriş niteliği taşıdığından uygulamayı basit tutmaya çalıştım. Eğer takıldığınız veya daha fazla açıklanmasını istediğiniz noktalar olursa yorumlarınızı beklerim.

(Sıradaki konu : "C# ile video işleme")

Görüntü İşleme (C#) - Uygulama

Mart 19, 2009 15:37 tarihinde dandelo tarafndan eklenmistir.

gi    Daha önce "burada" genel olarak bahsettiğim ve kullanılacak kod bloğunu tanıttığım "C# ile Görüntü İşleme"yi bir kaç örnek üzerinde anlatmaya çalışacağım.Bir görüntü üzerinde yapılabilecek işlemleri noktasal, alansal, toplamsal, biçimsel gibi alt kategorilere bölebiliriz.

    Öncelikli olarak noktasal işlemlerden bahsedersek, noktasal işlemler; görüntü üzerinde gözek gözek dolaşıp, her gözekin sadece kendi değerini değiştirdiğimiz işlemlerdir. Örnek olarak parlaklık(brightness) , zıtlık(contrast), gritona çevirme, negatif ve eşikleme gibi işlemleri verebiliriz. Alansal işlemler ise sadece bir gözekle değil birbirine komşu birkaç gözekle yapılan işlemlerdir. En bilinen örneği filtrelerdir. Örneğin bir resme medyan filtresi uygulamak istediğimizde seçilen yapısal elemana göre (3x3 veya 5x5) o bölgedeki tüm gözeklerin değeri hesaplanıp yapısal elemanın ortasındaki değere yazılır. Biçimsel işlemler, resmin renk değerlerinde değil de biçiminde yapılan değişikliklerdir. Balık gözü(fish eye), girdap(twirl) ve gözekleme(pixelate) gibi. Toplamsal işlemlere de Fourier dönüşümünü örnek verebiliriz.

    Noktasal işlemlerin birkaçından genel olarak bahsedip sadece parlaklık üzerinde duracağım. Diğer işlemlere de ilerleyen günlerde Kod Kütüphanesinde yer vereceğim.

    Bir gözeğin renk değerlerinin 0 ile 255 arasında değiştiğinden bahsetmiştik. Değerler 255 e yaklaştıkça o gözeğin parlaklığı artar. Bunun için bir resmin parlaklığını artırmak için , resmin tüm gözeklerinin renk değerlerini artırmalıyız. Kod üzerinde açıklarsak;

(daha basit ve anlaşılır olduğu için 32bitlik formatı tercih ettim.)

  public Bitmap parlat(Bitmap resim, int değer)
        {
            unsafe
            {
                BitmapData bmpdata = resim.LockBits(new Rectangle(0, 0, resim.Width, resim.Height),
                        ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb);

                byte* p = (byte*)bmpdata.Scan0;

                for (int i = 0; i < bmpdata.Height; i++)
                {
                    for (int h = 0; h < bmpdata.Width; h++)
                    {
                        p[0] =Convert.ToByte( p[0]+değer );
                        p[1] =Convert.ToByte( p[1]+değer );
                        p[2] =Convert.ToByte( p[2]+değer );

                        p += 4;
                    }
                }

                resim.UnlockBits(bmpdata);

                return resim;
            }
        }

    Burada 'resim' gözek gözek dolaşılmakta ve renk değerleri, girilen 'değer' parametresi kadar artırılmaktadır. Yalnız burda dikket edilmesi gerekilen nokta renk değerlerinin 0-255 arasında değişmesidir. Eğer değerler bu sınırı geçerse program hata verecektir. Onun için her artırmada değerler kontol edilip 255'i geçenler 255'e, 0'ın altına inenlerde 0'a eşitlenmelidir. Düzeltilmiş kısım ;

for (int i = 0; i < bmpdata.Height; i++)
{
    for (int h = 0; h < bmpdata.Width; h++)
    {  
        //mavi için
        if (p[0] + değer > 255)     p[0] = 255;  
        else if(p[0] + değer < 0 )  p[0] = 0 ;   
        else   p[0] =Convert.ToByte( p[0]+değer );

        //yeşil için
        if (p[1] + değer > 255)     p[1] = 255; 
        else if (p[1] + değer < 0)  p[1] = 0;    
        else  p[1] = Convert.ToByte( p[1] + değer);

        //kırmızı için
        if (p[2] + değer > 255)     p[2] = 255; 
        else if (p[2] + değer < 0)  p[2] = 0;    
        else  p[2] = Convert.ToByte(p[2] + değer);

        p += 4;
    }
}

  

    Bu yöntem pekde doğru bir algoritma olmayıp, görüntü işlemenin matnığını anlatmak için verdim. Parlaklık için çeşitli fonksiyonlar internette bulunabilir.

    Diğer noktasal işlemlerden biraz bahsedecek olursak; bir görüntünün tersini(negatifini), tüm gözeklerin renk değerlerini 255 den çıkararak elde ederiz. 

for (int i = 0; i < bmpdata.Height; i++)
{
    for (int h = 0; h < bmpdata.Width; h++)
    {
        p[0] = Convert.ToByte(255 - p[0]);
        p[1] = Convert.ToByte(255 - p[1]);
        p[2] = Convert.ToByte(255 - p[2]);

        p += 4;
    }
}

    Bir resmi gritonlarına çevirmek için kırmızı, yeşil, mavi renk değerlerinn ortamasını alıp üç rengede bu değeri atıyarız. Yine  bu yönteme göre daha bir yöntem var olup bu yöntem, her rengi belli bir oranda işleme katar.

 for (int i = 0; i < bmpdata.Height; i++)
{
    for (int h = 0; h < bmpdata.Width; h++)
    {
        byte ort = Convert.ToByte((p[0] + p[1] + p[2]) / 3);
        p[0] = p[1] = p[2] = ort;
        p += 4;
    }
}

Daha başka bol kodlu günlerde görüşmek üzere...

 


C Omega (Cω)

Nisan 16, 2008 11:25 tarihinde dandelo tarafndan eklenmistir.

C Omega, Microsoft Research tarafından geliştirilen, tamamen deneysel bir araştırma projesidir.C Omega dilini geliştiren ekip, deneme yanılma yoluyla yenilikler geliştirerek C# 'ın geliştirilmesine yardımcı olmaktadır.Microsoft tarafından yapılan açıklamaya göre, C Omega'yı ticari bir dile dönüştürme planları olmayıp, herhangi bir ürüne entegre edilmeside düşünülmemektedir.

C Omega, hiyerarşik veri (XML), ilişkili veri (SQL) ve .Net Common Type sistemlerinin arasındaki uçurumu köprülemek için yazılmış "veriye yönelik programlama" dır.Başka bir deyişle , XML, SQL ve CTS in genelleştirme mantığı ile birleştirilmiş ortak bir dildir.Veri yapısı açısından bakarsak C Omega ile amaçlanan, ilişkili ve XML veri modeli ile SQL in entegrasyonu sunacak şekilde C#'ı geliştirmektir. Daha iyi anlamak için bir örnek verecek olursak ;

public class card
{
    sequence
    {
        string  name;
        string  title;
        string  email;
        string? phone;
        logo?   logo;
    };
}

public class logo
{
    attribute string url;
}

public class Test
{
    static void Main()
    {
        card c = <card/>
                   <name>John Doe</name>
                   <title>CEO, Widget Inc.</title>
                   <email>john.doe@widget.com</email>
                   <phone>(202) 456-1414</phone>
                   <logo url="widget.gif"/>
                 </card/>;
        c.*.{ Console.WriteLine(it); };
    }
}

 

Örneğin yukarıdaki kodun içine gömülmüş olan aşağıdaki XML kodu gibi.


<card/>

                   <name>John Doe</name>

                   <title>CEO, Widget Inc.</title>

                   <email>john.doe@widget.com</email>

                   <phone>(202) 456-1414</phone>

                   <logo url="widget.gif"/>

</card/>

Ticari bir dil olarak geliştirmeyi düşünmüyoruz da deseler bu Microsot'un ne yapacağı belli olmaz diyerekten bu dili takip etmeye değer diyorum. Bu özelliklerinin bir de C# a eklendiğini düşünsenize. Belli mi olur bakarsınız .Net 4.0 ile C# dada kullanabiliriz belkide.