Yapay zeka, klasik programlama yöntemleriyle
çözülemeyen problemleri çözmeye yarayan yöntemlerin bütünüdür diyebiliriz. Bu
yöntemde, bir veriden bir sonuç çıkartılması için, ilk önce ham
verinin işlenip, girdi kümesinin küçültülmesi gerekir. Yapay zeka yöntemlerinden
biri olan sayısal görüntü işleme alanında da, girdi olarak
verilen bir resmin, gereksiz verilerden arındırılması
gerekir. Bu makalede, Java’da basit görüntü
işlemeyi ve sayısal görüntü işleme yönteminde çok
kullanılan bir yöntem olan histogram eşitlemeyi
anlatacağım. İlk önce Java’da resim
dosyalarını nasıl yükleyeceğimizle başlayalım.
Java’da her sayısal görüntü veri yapısı Image
sınıfından türetilir. Image sınıfı, tek
başına pek kullanılmaz, daha çok bu sınıftan türetilen
BufferedImage ve VolatileImage yapıları
kullanılır. Ben bu makalede BufferedImage
yapısını kullandım. Bu sınıfları kullanabilmek için
programın başına;
<code>
import java.awt.*;
import java.awt.image.*;
</code> |
yazmamız gerekiyor. Programda BufferedImage
sınıfını kullanacağımızı
söylemiştik. Önce BufferedImage sınıfındaki
bazı metodlara bakalım.
getGraphics() |
BufferedImage
sınıfının, üzerinde işlem yapılabilecek olan Graphics
nesnesini döndürür. |
getHeight() |
Resmin satır sayısını
döndürür. |
getWidth() |
Resmin sutun sayısını
döndürür. |
getRGB(int x, int y) |
Resmin (x,y) koordinatındaki piksel
değerini döndürür. |
setRGB(int x, int y) |
Resmin (x,y) koordinatındaki piksel
değerini setler. |
Bir BufferedImage nesnesini
kullanabilmek için, bir Image nesnesine yüklediğimiz resmi BufferedImage
nesnesine çizmemiz gerekir. Resmimizi BufferedImage nesnesine
yüklediğimize göre, üzerinde işlem yapmaya başlayabiliriz.
<code>
private boolean yukle(String konum){
…
try
{
im =
Toolkit.getDefaultToolkit().getImage(konum);
bim = new
BufferedImage(im.getWidth(null), im.getHeight(null),
BufferedImage.TYPE_INT_RGB);
bim.getGraphics().drawImage(im, 0, 0,
null);
}
catch(Exception exc)
{
JOptionPane.showMessageDialog(null,
"Yuklemede Hata", "Hata", JOptionPane.ERROR_MESSAGE);
return false;
}
return true;
}
</code> |
Histogram eşitleme:
Resim üzerinde piksel işlemleri yapmak
için ilk bilinmesi gereken, piksellerin değerlerinin ne şekilde
tutulduğudur. Java da piksel değerleri, Mavi(B), Yeşil(Y),
Kırmızı(R) ve Transparency(Şeffaflık)(T)
değerlerinden oluşur. Bu değerlerin 32 bitlik bir tamsayı
üzerinde;
0-7. bitler B
8-15. bitler G
16- 23. bitler R
24-31. bitler T |
değerlerini oluşturur. Bu değerleri elde etmek için (p
pikselimizin sayı değeri olmak üzere);
B = p&(0xFF)
G = (p>>>8)&0xFF
R = (p>>>16)&0xFF
T = (p>>>24)&0xFF |
işlemleri yapılır. Bu örnekte işlemler sadece renkler
üzerinde yapılacak, T değeri işlenmeyecektir. Histogram eşitleme yönteminin amacı;
bir resimdeki piksel değerlerinin histogramını
çizdiğimizde, bir sayıya doğru yığılma oluyorsa,
bu yığılmayı azaltmak ve sayıları
dağıtmaktır. Bu yöntem ile karanlık çekilmiş bir resim
daha belirgin hale getirilebilir.
Histogram eşitleme yöntemi 3 adımda
gerçekleştirilir.
1) Her bir sayı için ( 0 – 255), piksel
değeri o sayıya ait olan piksellerin toplamı bulunur.
<code>
int array[][] = new int[3][256];
for(int i = 0;i<array.length;++i)
{
//0: B, 1: G, 2: R
for(int k = 0;k<bim.getHeight();++k)
{
for(int j =
0;j<bim.getWidth();++j)
{
array[i][ ( bim.getRGB(j, k) >>> (i*8) ) & 0xFF ]++;
}
}
}
</code> |
2) Bu dizideki her bir eleman, bir önceki
elemanın değeriyle toplanır.
<code>
int payda = bim.getHeight() * bim.getWidth();
for(int i = 0;i<array.length;++i)
{
for(int k = 1;k<array[i].length;++k)
{
array[i][k]
+= array[i][k-1];
}
}
</code> |
3) Sonuçta çıkan dizideki her eleman,
resimdeki piksel sayısına bölünür ve en yüksek piksel değeri ile
çarpılır.
<code>
for(int i = 0;i<array.length;++i)
{
for(int k = 0;k<array[i].length;++k)
{
array[i][k]
/= payda;
array[i][k]
*= 255;
}
}
</code> |
Bu işlemleri
yaptığımızda, elimizde 256 elemanlı bir dizi
bulunacaktır. Elimizdeki diziyi tekrar resime aktarmamiz gerekmektedir. Tek
yapmamiz gereken, her piksele (eğer dizinin piksel değeri a ise)
dizideki a. elemanı atamamız olacaktır.
<code>
int value, temp;
for(int i = 0;i<bim.getHeight();++i)
{
for(int k = 0;k<bim.getWidth();++k)
{
value =
bim.getRGB(k, i);
value &=
0xFF000000;//T değerinin aynı kalmasını sağlar.
for(int j =
0;j<array.length;++j)
{
//R,G,B değerleri için ayrı ayrı
temp = ((bim.getRGB(k, i))>>>(j*8))&0xFF;
temp = array[j][temp];
temp = temp<<(8*j);
value |= temp;
}
bim.setRGB(k,
i, value);
}
}
</code> |
Histogram eşitlemenin kullanım
alanları:
İyi hoş, biz bunları
yaptık ama ne işe yarayacak diyebilirsiniz. Histogram eşitleme, bir çok yöntem için
kullanışlı bir metoddur. Bir resimdeki nesneleri saydırmak
için (mesela greysacale, kötü kalitede bir resimdeki pirinçler) , resmi ilk önce
histogram eşitlemeden geçirirsek saydırmak kolay olacaktır. Yada, en basitinden, kendi çekmiş
olduğunuz ama flaşın yetmediği fotoğrafları
histogram eşitlemeden geçirirseniz, fotoğraflar daha belirgin
olacaktır.
Orhan Özalp
Ege Üniversitesi Bilgisayar Mühendisliği
Bölümü
[email protected]
Makale:
Java ile Histogram Eşitleme J# ve Java dili Orhan Özalp
|