SİTE
İÇİ ARAMA |
|
Blogroll |
|
|
|
GDI+ ile Resim İşleme(Image Processing) |
|
Gönderiliyor lütfen bekleyin... |
|
|
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 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....
Örnek Uygulamayı İndirmek
İçin Tıklayın.
Zeki
Yuğnak
Erciyes Üniversitesi
Elektronik Mühendisliği
Makale:
GDI+ ile Resim İşleme(Image Processing) C++ ve C++.NET dili Zeki Yuğnak
|
|
|
-
-
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
|
|
|