HSV-RGB Uzay Dönüşümü

HSV renk uzayı renkleri içerdiği RGB değerlerine göre değilde Hue (Renk Özü), Saturation(Doygunluk) ve Value(Parlaklık) değerlerine göre belirten bir renk uzayı türüdür.RGB renk uzayından HSV renk uzayına geçmek için gerekli olan kodu bu yazımda anlatmıştım. Bu yazımda ise HSV uzayında gerekli işlemleri yaptıktan sonra tekrar RGB uzayına döndürmeyi anlatacağım. Ters dönüşüm işlemi için önceki yazımda bahsettiğim nedenlerden dolayı H S V değerlerini 0-255 arasında değiştiğini varsayacağım. Böylelikle bir önceki kodlarla RGB uzayından HSV uzayına dönüştürülen renkler bu yazımda yazdığım kodlar ile tekrar RGB uzayına dönüştürülebilecek. HSV uzayından RGB uzayına dönüştürme işlemi RGB uzayından HSV uzayına dönüştürme işleminden daha karmaşıktır.

Aşağıda dönüşümün 0-255 arasındaki HSV değerlerini 0-255 arasına dönüştürmek için gerekli olan algoritmayı görebilirsiniz.


Dönüşüm oldukça basit, matematiksel bir formüle dayandığından kodlama kısmı da rahatlıkla yapılabilir.

for(int i=0;i < kaynak.bminfo.width;i++) {
      for(int j=0;j < kaynak.bminfo.height;j++) {
          byte h=kaynak.pixels[i][j].red;
          byte s=kaynak.pixels[i][j].green;
          byte v=kaynak.pixels[i][j].blue;
             
          int deger= (int)(h/43)%6;
          double f= (double) ((double)h/43-(int)(h/43));
          int p=(int)(v*(255-s)/255);
          int q=(int)(v*(255-f*s)/255);
          int t=(int)(v*(255-(1-f)*s)/255);
       
          if(deger==0) { 
                    im.pixels[i][j].red=v;
                    im.pixels[i][j].green=t;
                    im.pixels[i][j].blue=p; }
          else if(deger==1) { 
                    im.pixels[i][j].red=q;
                    im.pixels[i][j].green=v;
                    im.pixels[i][j].blue=p; }
          else if(deger==2) { 
                    im.pixels[i][j].red=p;
                    im.pixels[i][j].green=v;
                    im.pixels[i][j].blue=t; }             
          else if(deger==3) { 
                    im.pixels[i][j].red=p;
                    im.pixels[i][j].green=q;
                    im.pixels[i][j].blue=v; }
          else if(deger==4) { 
                    im.pixels[i][j].red=t;
                    im.pixels[i][j].green=p;
                    im.pixels[i][j].blue=v; }
          else if(deger==5) { 
                    im.pixels[i][j].red=v;
                    im.pixels[i][j].green=p;
                    im.pixels[i][j].blue=q; }
       }
}
Yazılan kodlar ile HSV uzayındaki bir resim RGB uzayına çevrilebilir. Örnek olarak çok sevdiğim bir uygulamayı yapalım. Bir resmin içerisinde istediğimiz renkler dışında kalan renkleri gri tonlayan bir program yazmaya çalışalım. İlk bakışta akla gelmese de renk ayrımına dayalı işlerde HSV uzayının tercih edildiğini önceki yazımda söylemiştim. Resmi gri tonlamak içinde HSV değerlerinden S değerini 0 yapmak çok mantıklı bir yöntem olacaktır. Yani resmi açıyoruz, HSV uzayına dönüştürdükten sonra H değeri istediğimiz değerlerin dışında olan piksellerin S değerini 0 yapıyoruz ve daha sonra tekrar RGB uzayına dönerek resmi kaydediyoruz. Bu işlem için önceki yazılarımda anlattığım fonksiyonları da kullanarak aşağıdaki kodları oluşturabiliriz.
resim=resim_acm("istanbul.bmp");
yeni=resim_hsv(resim);

for(int i=0;i < yeni.bminfo.width;i++) {
    for(int j=0;j < yeni.bminfo.height;j++) {
         if((yeni.pixels[i][j].red < 20 || yeni.pixels[i][j].red > 50 )) { 
               yeni.pixels[i][j].green=0;//Saturation değeri burada saklanıyordu
         }
    }
}
yeni=resim_rgb(yeni);
resim_yaz(yeni,"ist_k.bmp");
Filtreleme için seçilen 20-50 değerleri filtrelenmek istenen renk için değişecektir. Bu örnekte kırmızı renkler dışında kalan renkler filtrelenmek istediğinden 20-50 değerleri seçilmiştir. Farklı değerler ve farklı örneklerle yapılan işlemlerin sonucu aşağıda gösterilmiştir.

hsv rgb dönüşümü

hsv rgb dönüşümü


hsv rgb dönüşümü

hsv rgb dönüşümü

9 yorum:

  1. öncelikle merhaba, merak ettiğim bir şeyi sormak istiyorum ; rgb renk uzayındaki her bir rengin temsil edildiği 0-255 aralığındaki decimal sayıların rengin oluşumundaki oranı nasıl hesaplanıyor? örneğin; r=232 g=34 b=123 değerindeki rengin oluşması için r'den şu kadar miktar g'den ve b'den şu kadar miktar diyebileceğimiz hesaplama nasıl oluyor yani gündelik hayatta bu rengi oluşturacağımız miktarları nasıl hesaplayabiliriz rgb renk uzayını referans alarak. şimdiden teşekkürler

    YanıtlaSil
    Yanıtlar
    1. Sanırım buna verilecek en güzel örnek Led ekranlardır. Burada temel eleman R-G-B ledlerin aynı kılıf içerisinde toplanması ile oluşturulmuş RGB Ledlerdir. Bu ledlerin Anot veya Katotları ortak olacak şekilde bağlanmıştır. Resimde de görüldüğü üzere diğer bacağına verilen gerilimde değiştirilerek istenen renk oluşturulur. Burada 0-255 denilen değeri en basit olarak 2-5 V arası gerlim seviyelerini temsil ediyor olarak düşünebilirsiniz. Yani R=232 için kırmızı ledin ucuna 2+(5-2)*232/255 = 4.729 Volt, G=34 için yeşil ledin ucuna 2+(5-2)*34/255 = 2.4 Volt ... şeklinde farklı gerilim seviyeleri ile 0-255 değerleri gerçeklenir. Böylece gerilim 2 volt iken led yanmazken (0), 5 volt olduğunda led maximum parlaklığında (255) yanacaktır. Basit olarak anlattığıma benzer olarak genellikle bu şekilde çok hassas gerilim verme işlemleri için pwm adı verilen bir modülasyon tekniği kullanılır. Bu teknikle seçilen bir çalışma frekansında, mesela 40Hz diyelim 1/40=25 ms , led her bir periyotta sabit bir gerilim altında (5V) Rx25/255 ms kadar yakılır. Yani led R=0 için 0 ms,232 için 22,74 ms, 255 için ise 25 ms yakılarak istenilen renk elde edilir.

      Sil
  2. merhaba kodu calıstıramıyorum hata alıyorum yardımcı olabılırsenız sevınırım

    YanıtlaSil
  3. Merhabalar,

    Yazılarda kodları verme amacım algoritma ve genel bir kullanımı hakkında bilgi sahibi olunması için. Burada verdiğim kodlarda okunurluğu kolaylaştırmak için bazen ufak sadeleştirmeler yapıyorum, çalışmama sebebi bu olsa gerek.

    Bunun haricinde çalıştığınız resim kesinlikle 24 bit BMP resmi olmalı ve resim açma/yazma gibi işlemler bu kütüphanedeki fonksiyonlar ile yapıldığından dosyalar/cbmp yolu altında bulabileceğiniz cbmp.h kütüphanesi projeye eklenmelidir.

    Sadece siteden indirdiğim kodlar ve kütüphane ile Dev C++ üzerinde kodları çalıştırmayı başardım. https://www.dropbox.com/s/38be7yd5nmam4ks/rgb2hsv.zip adresinden denemek için yazdığım koda ulaşabilir/tekrar çalıştırmayı deneyebilirsiniz.

    YanıtlaSil
  4. merhaba, RGB değerleri sınır değerlerini aşarsa ne olur? yani 0-255 i aşarsa. 256 yada 500 yaparsak

    YanıtlaSil
    Yanıtlar
    1. Merhaba, eğer HSV değerleri RGB-HSV dönüşümü ile elde edildi ise geri dönüşüm sonucunda da değerler RGB renk uzayı aralığında kalacaktır. En fazla yuvarlama hataları olabilir, yukarıdaki kodda bu sorun değişkenleri integer tanımlayarak çözülmüştü.

      Ancak diğer yazlarda (konvolüsyon gibi), renk değerleri 0-255 değerlerini aşmakta. Bu durumda gbyte_yap adını verdiğim fonksiyonu kullanmaktayım. Bu fonksiyon sıfırdan küçük değerleri sıfıra, 255 ten büyük değerleri 255 e atamakta.

      Sil
    2. çok sagolun burayı anladım....fakat html kodların da bu renk aralıgının geçtiğin mesala 277,300,261 yaptıgında renk oynaması oluyor bunun nedeni nedir ?

      Sil
    3. Kodu görmeden kesin olarak konuşamam. Ancak renk değerlerini tutan değişken char türünde tanımlanmışsa, sınırı aşan değerler 277= 277-256 = 21, 300 = 300 - 256 = 44 gibi değerlere yuvarlanmakta. İlk böyle bir olayla konvolüsyon yazımda karşılaşmıştım. Resimde renk geçişleri sırasında ani siyah ve beyazlar oluşuyordu. Sanırım karşılaştığınız böyle bir sorun.

      Sil
    4. tmm dır eyvvallah kardeşim sağol yardımın için

      Sil

Görüntü işleme ile ilgili yeni yazıları ve bu sitede yer alan yazıların güncellenmiş sürümlerini www.imlab.io veya cescript.github.io adreslerinden takip edebilirsiniz.

X