Renkli bir Resmi Gri Tonlamaya Dönüştürme

   Photoshop v.b. resim işleme uygulamalarında bulunan en basit işlemlerden birisidir renkli bir resmi gri tonlanmış haline dönüştürmek. Bu makalemde, C# ile renkli bir görüntüyü nasıl gri tonlanmış haline dönüştürebileceğimizi sizlerle paylaşıyor olacağım.

   Doğrudan kodlamaya geçmeden önce, konunun daha rahat anlaşılabilmesi adına, renkli görüntülerin bilgisayarlar tarafından nasıl tutulduğunu görelim. Renkli imajlar çoğunlukla çeşitli renk kanallarının bir araya gelmesiyle oluşmaktadır. Her bir piksel’in sahip olacağı gerçek renk ise bu piksele denk gelen renk kanalarındaki renklerin bir algoritma ile birleştirilmesiyle belirlenmektedir. Örneğin; RGB (Red-Green-Blue) renk modeli 3 ana renk olan kırmızı, mavi ve yeşil’in tonlarının bulunduğu kanallara sahiptir ve her bir pikselin rengi bu üç rengin tonlarının birleşmesiyle oluşmaktadır. Benzer şekilde; CMYK (Cyan-Magenta-Yellow-Key) renk modelinde camgöbeği (mavi), pembe, sarı ve mavi renk tonlarının bulunduğu kanallara sahiptir. Kodlanması ve işlenmesinin daha kolay olması nedeniyle makalemin devamında işlemleri RGB renk modeli üzerinden anlatıyor olacağım.

   RGB renk modelinde gri tonda bir renk elde edebilmek için her üç kanalın da aynı değere sahip olması gerekecektir. RGB modelindeki her bir kanalın sadece 0 ile 255 arasında bir değere sahip olacağı da düşünülecek olursa, gri tonlama için sadece 255 farklı seçeneğe sahip olduğumuz sonucuna ulaşmak hiçte zor olmayacaktır. Aşağıda, örnek bir imajın RGB kanallarındaki görünümleri ile bunların gri tondaki karşılıkları görülebilir;

RGB renk modelinde renk kanalları ve gri tonlamaları

   Gri tonlamaya sahip olabilmek için RGB renk modelindeki her bir kanala aynı değeri vermemiz gerektiğini artık bildiğimize göre, sıra geldi bu değeri nasıl hesaplayacağımıza. İlk akla gelen hesaplama yöntemi her üç kanalın değerlerinin aritmetik ortalamasını kullanmak olacaktır sanırım; ama ortaya çıkacak olan görüntü pek de göze hoş gözükmeyecektir. Bu dönüşümde en sık kullanılan yöntem, her bir pikselin aydınlık derecesini bularak bu değeri kullanmaktır. Bir pikselin aydınlık derecesi ise kırmızı kanalının %30’u, yeşil kanalın %59’u ve mavi kanalın %11’i alınarak toplanması neticesinde bulunmaktadır. Aşağıda her iki yöntem ile hazırlanmış olan gri tonlanmış imajlara birer örnek bulabilirsiniz;

Aritmatik ortalama yöntemi ile gri tonlaması yapılmış bir imajimage

 

 

 

 

 

 

 

 

 

   Sanırım bilgisayarlarda görüntünün tutulması, renk modelleri ve gri tonlama hakkında şimdiye kadar sizlerle paylaştıklarım kodlamaya geçmemiz için yeterli olacaktır. Bu bilgileri ışığında bir uygulama geliştirmenin ne kadar kolay olacağını sizlerde farketmişsinizdir.

   Öncelikle oluşturacağımız gri tonlanmış görüntüyü saklayacağımız bitmap nesnemizi oluşturalım;

var griImaj = new Bitmap(orjinalImaj.Width, orjinalImaj.Height);

   Ardından da orjinal imajımızın her bir pikseli için gri tonlama değerini hesaplayalım;

var orjinalRenk = orjinalImaj.GetPixel(i, j);
var griTon = (int)((orjinalRenk.R * .3) + (orjinalRenk.G * .59) + (orjinalRenk.B * .11));

   Kod parçasından da görüleceği gibi gri tonlama için yüzde değerlerinin hesaplanmasında çarpma/bölme işlemleri yapmak yerine doğrudan hesaplanan ondalık değer ile çarpılması daha hızlı bir sonuç verecektir. Devamında, elde ettiğimiz gri ton değerinden bir renk oluşturalım;

var griTonRenk = Color.FromArgb(griTon, griTon, griTon);

   ve bu rengi griImaj nesnemizde ilgili piksel rengi olarak atayalım;

griImaj.SetPixel(i, j, griTonRenk);

   Bu işlemi her bir piksel için yaptıktan sonra nihai olarka griImaj’ımızı formumuz üzerindeki pictureBox’ımıza atayabiliriz;

pbGri.Image = griImaj;

   Tüm bu işlemler ardından aşağıdaki çıktı alınacaktır;

Renkli görüntünün işlenmesi sonrasında ortaya çıkan gri tonlanmış görüntü

  Kodumuzu toparladığımızda ise aşağıdaki kod parçacığı oluşacaktır;

var orjinalImaj = new Bitmap(pbOrjinal.Image);
 
var griImaj = new Bitmap(orjinalImaj.Width, orjinalImaj.Height);
 
for (int i = 0; i < orjinalImaj.Width; i++) {
    for (int j = 0; j < orjinalImaj.Height; j++) {
        var orjinalRenk = orjinalImaj.GetPixel(i, j);
 
        var griTon = (int)((orjinalRenk.R * .3) + (orjinalRenk.G * .59) + (orjinalRenk.B * .11));
        var griTonRenk = Color.FromArgb(griTon, griTon, griTon);
 
        griImaj.SetPixel(i, j, griTonRenk);
    }
}
 
pbGri.Image = griImaj;

   Her ne kadar sizlerle paylaşmış olduğum yöntem temelde renkli görüntüleri gri tonlama görüntüye dönüştürüyor olsa da büyük boyutlu resimlerde yavaş işleyeceği bir gerçek. Bu yüzden, büyük boyutlu resimleri işlemek için temelde yatan mantık korunarak alternatif çözümler üretilmesi gerekecektir.

Fatih Boy

Ankara'da yaşayan Fatih, bir kamu kurumunda danışman olarak çalışmaktadır. ALM süreçleri, kurumsal veri yolu sistemleri, kurumsal altyapı ve yazılım geliştirme konularında destek vermektedir. Boş zamanlarında açık kaynak kodlu projeler geliştirmeyi ve bilgisini yazdığı makalelerle paylaşmayı seven Fatih, aynı zamanda Visual C# ve Visual Studio teknolojileri konusundan Microsoft tarafından altı yıl üst üste MVP (En Değerli Profesyonel) ödülüne layık görülmüştür. İş hayatı boyunca masaüstü uygulamaları, web teknolojileri, akıllı istemciler gibi konularda Asp.Net, Php, C#, Java programlama dilleri ve MySql, MsSql ve Oracle gibi veritabanı yönetim yazılımları ile çalışmıştır. İngilizce ve Türkçe olarak yayınlanan makalelerini gerek İngilizce bloğunda, gerekse de Türkçe bloğunda bulabileceğiniz gibi web sitesinden de açık kaynak kodlu geliştirdiği yazılımlarına ulaşabilirsiniz. vCard - Twitter - Facebook - Google+

Bir Cevap Yazın

E-posta hesabınız yayımlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir