İçindekilerGirişİndex
YukarıİlkÖncekiSonrakiSon
Geriİleri
Yazdır
Onder Teker
on_der_tek_er@yahoo.com

Java'da Görüntü İşleme (Image Processing)

Görüntü İşleme ve Java

Görüntü İşleme, bir image'ın başka bir image'a dönüştürülmesidir. Java 2D API'si görüntü işlemekte kullanılacak bir çok class içermektedir. O yüzden programcının tek yapması gereken bir kaç class'ın instace'ını yaratmak ve bir kaç method çağırmaktır. Image'ın tek tek pixelleriyle işlem yapmaya gerek yok. Bu makalede Convolve ve Transform operasyonları incelenecektir ki bunlar zaten java.awt.image paketinde implement edilmiştir.

Görüntü işleme operatörleri Image class'ıyla değil BufferedImage class'ıyla çalışır. BufferedImage zaten Image class'ını extend ettiği için, Image kullanılan her yerde, örneğin bir canvas'ın paint methodunda Graphics class'ına ait drawImage() methodunda kullanılabilir. Ancak, elimizde zaten Image varsa, bunun BufferedImage'a çevrilmesi gerekir. Çünkü her BufferedImage bir Image'dır ama her Image bir BufferedImage değildir. Örneğin Toolkit ve Component class'larındaki createImage() method'uyla yaratılan image'lar doğrudan image processing için kullanılamazlar. Bir Image'ı BufferedImage'a çevirmek için en kolay yöntem, BufferedImage'ın Graphics'ini alıp Image'ı ona çizmektir. Bunun için şöyle bir method yamak uygun olur :

	private BufferedImage converImageToBufferedImage(
		Image image,ImageObserver observer)
	{
		int width=image.getWidth(this);
		int height=image.getHeight(this);
		BufferedImage buffered=new BufferedImage(width,height,BufferedImage.TYPE_INT_RGB);
		Graphics g=buffered.createGraphics();
		g.setColor(Color.white);
		g.fillRect(0,0,width,height);
	 	g.drawImage(image,0,0,null);
		return buffered;
	}

Burada orjinal image'ın enini-boyunu öğrenmek için kullınlan methodlara ImageObserver olarak Canvas veya herhangi bir Component verilebilir. En ve boy belliyse buna gerek olmayabilir.BufferedImage'a öncelikle beyaz bir dikdörtgen çizilmiştir. Eğer image'da saydam bir yer yoksa buna gerek olmayabilir. Yukarıdaki method daha basit yazılabilir.

	private BufferedImage converImageToBufferedImage(
		Image image,int width,int height,ImageObserver observer)
	{
		BufferedImage buffered=new BufferedImage(w,h,BufferedImage.TYPE_INT_RGB);
		Graphics g=buffered.createGraphics();
		g.drawImage(image,0,0,null);
		return buffered;
	}

Image Operatörleri

Java'da image operasyonu yapan class'lar BufferedImageOp interface'ini implement ederler. Bunların

	public BufferedImage filter(BufferedImage src,BufferedImage dest)

şeklinde bir method'ları bulunur. Renk değerlerini src'den (source'dan) alıp sonucu dest'e (destination'a) kaydederler. Sonuç olarak yine destination image'ı döner. Eğre 'dest' parameteresi null'sa yeni bir image yaratılıp o döndürülür. Değilse işlem dest'in üzerinde yapılır ve o tekrar geri döndürülür. Bu şekilde tekrar tekrar image yaratmak zorunda kalınmamış olur.

Convolve Operatörü

Image operatörü ConvolveOp, bir pixelin değerini, kendi ve etrafındaki pixel'lerin değerleriyle belirlendiği operatördür. Genellike bitişik olduğu pixellerle çalışılır. I. satır ve J. sütünundaki bir pixele P(I,J) ve sonuç olarak üretildiği image'daki değerine P'(I,J), katsayılara da KXX dersek :

P(I,J)=	  K11 * P(I-1,J-1)	+ K12 * P(I-1,J)	+ K13 * P(I-1,J+1)
	+ K21 * P(I,J-1)	+ K22 * P(I,J)		+ K23 * P(I,J+1)
	+ K31 * P(I+1,J-1)	+ K32 * P(I+1,J)	+ K33 * P(I+1,J+1)

şeklinde bir formul elde edilir, bitişik komşular için. Burada K 3x3 bir matris olarak verilebilir :

K=
K11K12K13
K21K22K23
K31K32K33

İşte bu matrise Kernel denir. Buna göre bir image'ı convelve operatöründen geçirmek için

	float[] data=new float[]{0.1f,0.1f,0.1f,0.1f,0.2f,0.1f,0.1f,0.1f,0.1f,0.1f};
	Kernel kernel=new Kernel(3,3,data);
	ConvolveOp op=new ConvolveOp(kernel);
	op.filter(src,dest);

şeklinde bir kod yeterlidir. 3x3 kernel matrisi 9 elemanlı bir dizi olarak verilir. Buradaki katsayılar istenen etkiye göre belirlenir. Örnekteki değerler image'ı daha yumuşak yapma etkisi verir. Rengi açmak için :

	float[] data=new float[]{0f,0f,0f,0f,1.5f,0f,0f,0f,0f,0f};

gibi bir değer vermek yeterlidir. Ortadaki değer P'(I,J)'nin P(I,J)'nin kaç katı olacağını belirler. P'(I,J), diğer değerler 0'sa çevresindekilere bağlı değil demektir. 1.5 yerine 0.5 konursa karanlık etkisi verilir.

Affine Transform Operatör'ü

Bu operatörler, image'da renk değerlerini değil konumları değiştiriler. Döndürmek, kaydırmak, büyütmek, küçültümek gibi 'Affine Transform'lar uygularlar. P(x,y) değeri bir matrisle çarılıp P(x',y') konumuna gider. AffineTransform class'ında tutularn matris

P'
x'
y'
1
=
Affine Transform
m00m01m02
m10m11m12
001
*
P
x
y
1
=
P'
m00x + m01y + m02
m10x + m11y + m12
1

AffineTransform class'ı dönüşüm matrisindeki değerleri istenen yönde değiştiren rotate(), scale() gibi methodlar içerir. Matrisin değerlerini programcı kendi hesaplamak veya bulmak zorunda kalmaz. Bütün operasyonlar bittikten sonra AffineTransform matrisi operatöre verilir. Örneğin bir image'ı belli bir C(cx,cy) noktasına döndürmek için.

	AffineTransform transform=new AffineTransform();
	transform.translate(cx,cy);
	transform.rotate(angle);
	transform.translate(-cx,-cy);
	AffineTransformOp op=new AffineTransformOp(transform,null);
	op.filter(src,dest);

Bir noktaya göre döndürme yapmak için bir image'ın önce C(cx,cy) noktasına taşınması sonra döndürülmesi daha sonra da eski noktasına geri getirilmesi gerekmektedir. Bu operasyonlar önce AffineTransform class'ında yapıldığı için image bir operasyonlar dönüştürülebilmektedir.

Görüldüğü gibi Java'da image processing hiç de zor değildir. Çünkü standart ve basit bir kütüphanesi vardır. Sadece java.awt.image'de olan özellikleri kullanarak bir görüntü işleme uygulaması yapılabilir. Bunun için Java'yı bilmek yeterlidir.

İçindekilerGirişİndex
YukarıİlkÖncekiSonrakiSon
Geriİleri
Yazdır