film indir
Ocak
4th 2008
GDI+ ile Resim İşleme(Image Processing)

Posted under C# (csharp)



Bu yazıda Gdi kütüphanesi ile basit görüntü işleme tekniklerinin, bir resim üzerinde uygulanmasını ele alacağız. Bu teknikleri kullanarak resimler üzerinde gamma - gray scale - brightness gibi efektlerin nasıl uygulanacağından ve bu efektlerin özelliklerinden bahsedeceğiz. Ayrıca bu sayede bitmap yapısınada kısaca bir göz atmış olacağız. Aşağıda yapılmış basit bir uygulamanın resmini görmektensiniz. Birazdan bu efektlerin nasıl yapıldığını açıklayacağız.



Efektlerin bir resim üzerinde uygulanması şu şekildedir; ilk olarak resmin pixellerini elde ederiz ve bunları sistematik bir şekilde matemetiksel işlemler uygulayarak değiştiririz. Burada bahsedeceğimiz efektler sistematik belli formüller dahilinde yapılan efektlerdir.Fakat sistematik yapılmayan efektlerde vardır mesela noise efekti. İlerki yazılarımda basit bir filitre mantığından bahsederken bu efekti de gözden geçireceğiz.

Efektlerden bahsetmeden önce bir resim üzerinde pixel bazında nasıl değişiklik yapılacağından bahsedelim ve biraz da bitmap yapısına değinelim. Aşağıdaki kodda basit bir bitmapin nasıl oluşturulacağını görebiliriniz.

   CBitmap bitmap;
   bitmap.CreateCompatibleBitmap (&dc, 100, 100);

Bitmap pixellerden oluşan bir yapıdır. Pixel ise bir renk tonudur. Biz bu uygulamada 24 bit renk derinliğini kullanacağız. Yani bunun için tonları 0-255 arasında olabilecek 3 renge ihtiyacımız var. Bunlar kırmızı,yeşil ve mavi renkleridir. Aşağıda bir pixelin renk değerlerinin nasıl elde edildiğinden bahsedeceğiz. Mfc de bir bitmap oluşturmak için hazır bir sınıf bulunmaktadır (CBitmap).Boyutları belli olan bir bitmap yaratmak için bu sınıfın CreateCompatibleBitmap adlı fonksiyonunu kullanırız.Bu fonksiyoni,boyutlarıı belirleyebileceğimiz kullanılabir bir bitmap oluşturmamıza izin verir.Fakat bitmap üzerinde pixel bazında işlemler yapabilmek için bu sınıf yeterli değildir.Bunun için bir Dc nesnesine ihtiyaç vardır.İşte bunun için CDC sınıfından bir nesne oluşturmamız gerekir.Bunu şu şekilde yapabiliriz.



   CDC dcMem; //Bitmap i seçmek için kullanacağımız dc
   dcMem.CreateCompatibleDC (&dcScreen);//dcScreen programın an dc nesnesi
   dcMem.SelectObject (&bitmap); //bitmap i seçiyoruz

       

Burda CDC sınıfından türettiğimiz dc nesnesini kullanabilmemiz için bunu başka bir dc nesnesi ile bağlantılı şekilde yaratmamız gerekir.Burda dc nesnesini oluşturmak için CreateCompatibleDC fonksiyonundan yararlandık bu fonksiyon parametre olarak başka bir dc nesnesi istemektedir.Bunun için asıl çizim yaptığımız dc nesnesini kullandık(dcScreen).Sonra istediğimiz bitmap i oluşturduğumuz bu nesneye seçebiliriz.Bir bitmap i görünüme çizmek için ise CDC sınıfının BitBlt fonksiyonunu kullanablirsiniz.Aşağıdaki uygulamasını görebilirsiniz.

  dcScreen.BitBlt (0, 0, 100, 100,&dcMem, 0, 0, SRCCOPY);

Artık dc nesnemizi yarttığımıza göre artık pixel bazında işlemlere geçebiliriz.Bu işlemler için CDC sınıfının GetPixel() ve SetPixel() fonksiyonlarını kullanabiliriz.GetPixel() fonksiyonu nu bitmap ten pixel değerlerini almak için kullanacağız.Bu fonksiyon dönüş değeri olarak bir renk değeri dönderir ve bu değeri matematiksel işlemlerle isteğimiz şekilde değiştirdikten sonra bu değerleri, pixel değerlerini değiştirmek için kullanacağımız SetPixel() fonksiyonuna parametre olarak geçirebiliriz ve böylece resim üzerinde istediğimiz değişikliği yapmış oluruz.Pixellerden elde ettiğimiz değerler renk değeridir ve bu mfc de COLORREF yapısı ile tanımlanmıştır.Bu yapı ya değer verilirken RGB makrosunu kullanırız.RGB makrosu 3 adet integer değer içermektedir.Bunlar Red,Green,Blue değerleridir.Şimdi bir bitmap e bir resmin nasıl okunacağını görelim.

  bitmap.m_hObject=(HBITMAP)LoadImage(theApp.m_hInstance,”resim.bmp”,IMAGE_BITMAP, 0, 0,
                                                                     LR_LOADFROMFILE | LR_DEFAULTSIZE);

Bunun için LoadImage fonksiyonunu kullandık.Fonksiyonun ikinci paremetresine istediğimiz bmp formatındaki resmin ismini verdik.Fonksiyonun diğer parametreleride değinmeyeceğim.

Bu konularada değindikten sonra isterseniz bir bitmap ten pixel değerlerini nasıl elde edilebileceğinden bahsedelim.Yukarda bahsettiğimi gibi bunun için GetPixel() fonksitonunu kullanacağız.Aşağıda kodu görebilirsiniz.

COLORREF color;
   for(int y=0;y<100;y++)
     {
       for(int x=0;x<100;x++)
        {
           color=dcMem.GetPixel(x,y);

           int r=GetRValue(color);
           int g=GetGValue(color);
           int b=GetBValue(color);

           r+=1;
           g+=1;
           b+=1;
           color=RGB(gray,gray,gray);
           usedc.SetPixel(x,y,color);
       }
    }

İlk olrak bu işlemi iki tane for döngüsü içerisinde yaptık,Çünkü yukarda yarattığımız bitmap in boyutları 100,100 dü.Yani bizim resmimiz 10.0000 adet pixel değeri içermektedir.Pixellerin renk değerini sırayla GetPixel() fonksiyonunu kullanarak COLORREF ten türettiğimiz color değişkenimize aldık.Bir aşağı satırda ise GetRValue(),GetGValue(),GetBValue() fonksiyonlarını kullanarak pixel renk değerlerimizi integer değeri olarak elde ettik.Bu aşamadan sonra renk değerlerine istediğimiz işlemleri uygulayabiliriz.Burda sadece renk değerlerini 1 er artırdık ve bitmap i yeni renk değerleriyle yeniden oluşturduk.

İşimize yarayacak yapılardan ve fonksiyonlardan bahsettikten sonra artık efektleri incelemeye başlayabiliriz.Sırasıyla gray scale - gamma -brightness efektlerinden bahsedeceğim.

Gray Scale Efekti


orjinal resim


gray scale efekti uygulanmış resim

Yukardada resimdede gördüğünüz gibi resimden elde ettiğimiz pixel renk değerlerinden kırmızı,yeşil ve mavi yi ortak bir işleme sokarak tek bir renk elde ediyoruz ve yeni renk değerlerini kullnarak pixel pixel bitmap i tekrar oluşturuyoruz.Bu işlemi gerekleştirmek şu formülden yararlandık;

gray=0.299 * red + 0.587 * green + 0.114 * blue

Burada renk değerlerini belirlenmiş sabit sayısal değerlerle çarparak (0,299,0,587,0,114) ortak bir renk elde ettik.İki tane daha gray scale yöntemi var bunlarında formüllerini vermek istiyorum.Bu formüllerde gene aynı sonucu vermektedir.

gray=0.2125 * red + 0.7154 * green + 0.0721 * blue

gray=0.5 * red + 0.419 * green + 0.081 * blue 

Şimdi bu işlemin kodla uygulanışına bakalım.


for(int y=0;y//bm.bmHeight resmin yükseklik değeri
    {
      for(int x=0;x//bm.bmWidth resmin genişlik değeri
        {
           color=usedc.GetPixel(x,y);

           r=GetRValue(color); //int r
           g=GetGValue(color); //int g
           b=GetBValue(color); //int r

           int gray=((r*0.299)+(g*0.587)+(b*0.114));

           color=RGB(gray,gray,gray); //COLORREF           
           usedc.SetPixel(x,y,color); //CDC den türttiğimiz nesnemiz
        }
    }

Gamma Efekti


orjinal resim

gamma efekti uygulanmış resim

gamma efekti uygulanmış resim

Gama değerleri resimden elde ettiğimiz pixel değerlerindeki renklerden bağımsız şekilde oluşturulur ve gama için gerekli olan renk değerleri 0.2 ile 5 arsında değişir.Gama değerleri 256 tanedir (0-255).Bunları elde etmek için şu formülü kullanırız.

red[i]=min(255, (int) ( (255.0 * pow(i/255.0, 1.0/r)) + 0.5 ) );
green[i]min(255, (int) ( (255.0 * pow(i/255.0, 1.0/g)) + 0.5 ) );
blue[i]min(255, (int) ( (255.0 * pow(i/255.0, 1.0/b)) + 0.5 ) );


0 dan 256 ya kadar bu değerleri buluruz ve rengimizin gama değerini bulmak için şöyle yaparız.Bitmap ten elte ettiğimiz renk değerleri şunlar olsun
m_red,m_green,m_blue ve yeni renk değerleri elde etmek için renk değerleri index olacak şekilde oluşturduğumuz gama değerleri dizisinden alırız.

m_red=red[m_red];
 m_green=green[m_green];
 m_blue=blue[m_blue];

Bu işlemi kodla şu şekilde yapabiliriz.
 //gama değerleri

 int red[256];
 int green[256];
 int blue[256];
 COLORREF color; //renkleri tutacağımız değişken

   int r,g,b;

UpdateData(); //kontrollerden verileri alıyoruz

   for(int i=0;i<256;i++)
    {

       //gama değerlerini hesaplıyoruz
       //m_vred,m_vgreen ve m_vblue programdaki slider barlardan alınan sayısal değerlerdir
	 red[i]=min(255, (int) ( (255.0 * pow(i/255.0, 1.0/(m_vred))) + 0.5 ) );
              green[i]=min(255, (int) ( (255.0 * pow(i/255.0, 1.0/(m_vgreen))) + 0.5 ) );
              blue[i]=min(255, (int) ( (255.0 * pow(i/255.0, 1.0/(m_vblue))) + 0.5 ) );
    }
    for(int y=0;y

            r=GetRValue(color);
            g=GetGValue(color);
            b=GetBValue(color);

           color=RGB(red[r],green[g],blue[b]);//renklerin gama değerini alıyoruz
           usedc.SetPixel(x,y,color);
        }
     }

Brightness Efekti


orjinal resim


brightness efekti uygulanmış resim


brightness efekti uygulanmış resim

Uygulanması en kolay efekttir.Yeni renk değerlerini oluşturmak için kendinize bir aralık belirlersiniz mesela (-100) - (100) arasında.Sonra bu aralıktan elde edilen değerleri bitmap tan aldığınız renk değerlerine ilave edersiniz.Sonrada elde ettiğimiz yeni renk değerlerini bir sınamadan geçiririz. Eğer değer 0 da küçükse 0, 255 ten büyükse 255 değerlerini veririz.

m_red+=m_brightness; m_green+=m_brightness; m_blue+=m_brightness;

Görüldüğü gibi uygulaması çok basittir.Eğer istersek her renk için ayrı bir parlaklık efekti uygulayabiliriz.Benim yazdığım kod ta her renk için ayrı parlaklık efekti uygulanmasına izin verilmiştir.Bu işlemin kod uygulamasını aşağıda inceleyebilirsiniz.


 COLORREF color;
         int r,g,b;
         UpdateData();

     for(int y=0;y

           r=GetRValue(color);
           g=GetGValue(color);
           b=GetBValue(color);

          //m_pos slider bardan aldığımız posisyon değeri

           int brighnes_r=(int)(r+m_pos);
           int brighnes_g=(int)(g+m_pos);
           int brighnes_b=(int)(b+m_pos);

          //m_kırmızı,m_yesil,m_mavi checkboxlardan alınmış bool tipinde değerler
           if(m_kirmizi)
            {
             if(brighnes_r<0) brighnes_r=0;
             if(brighnes_r>255) brighnes_r=255;
            }
           else
            {
             brighnes_r=r;
            }

           if(m_yesil)
            {
              if(brighnes_g<0) brighnes_g=0;
              if(brighnes_g>255) brighnes_g=255;
            }
           else
            {
              brighnes_g=g;
            }

           if(m_mavi)
            {
             if(brighnes_b<0) brighnes_b=0;
             if(brighnes_b>255) brighnes_b=255;
            }
           else
            {
             brighnes_b=b;
            }

             color=RGB( brighnes_r, brighnes_g, brighnes_b);

             usedc.SetPixel(x,y,color);
         }
     }

Bu yazımızında sonuna geldik.Görüntü işleme çok geniş bir konudur ve çok farklı alanlarda kullanılabilir.Biz bu yazıda sadece bir kaç görüntü efektinden bahsettik.Diğer yazılarımdada bu konulara daha fazla değineceğim ve diğer efektlerinde uygulanmasını göstereceğim.Genelde hep formüller kullanılarak işlem yapıldığından dolayı bu konular hakkında ayrıntılı anlatımlı bir kaynak fazla bulamazsınız.Ama Gdi ve gdi+ ile ugulamalar hakkında şu kitaptan ve siteden yararlanabilirsiniz. www.amazon.com www.codeproject.com İYİ ÇALIŞMALAR….

One Response to “GDI+ ile Resim İşleme(Image Processing)”

  1. fatih on 15 May 2008 at 06:05 #

    ben bu kanuda makalenın ıcın gercekten tessur edeım elınıze saglık

    ama aklımatakılan bı soru var bu yazdıgınız kodlar c# da calısıyomu??
    ben denemdım calısmadı variable ları tanımadı acama kutuphane mı eklememız gerekıyo

    kısa surede maıl atarsanız sevınırım

    ıyı calısmalar..

Trackback URI | Comments RSS

Yorum Yaz - Leave a Reply

yeliiniz Silinmitir.Ltfen Sayfanzdan Kodu Kaldrnz. Sayfa Bloggoayrılık yazılarıoyunlarkurye web tasarımı broşürlük dizi izle dizi izleKombi Tesisat Radyo DinleChat paysafe paysafe kartSohbet arkadaş travestitravesti travesti travesti Film izle Sicak Videolar Porno izle film izle e-okul arog Ask-i Memnu Sehitler Olmez sohbet Chat K�zlarla Sohbet sohbet chat kale kapi mirc Bedava Program Yukle Turkce Program Indir Celik Konstr�ksiyon evden eve nakliyat Toplist