RGB Dönüşüm Algoritmaları hakında

Başlatan Mucit23, 24 Şubat 2016, 12:20:55

Mucit23

RGB dataları üzerinde çalışıyorum. Bu başlık altında konu hakkında biraz fikir edinmek istiyorum.

İlk sorum şu olacak.

Kameralar ile çalışıyorum. Şuanda elimde çalışan OV9655 kamera var ve RGB565 formatında çıktı verip SDRAM üzerinde benim belirlediğim alana otomatik olarak pixel datalarını yazıyor.

LCD'i ARGB888 formatını destekliyor. Kamera ise RGB565 formatında çıktı veriyor. Normalde DMA2D donanımı RGB565 to RGB888 dönüşümünü yapıyor otomatik. Bunu ben yazılımla yapmak istesem nasıl yaparım? 5 Bit R, 6 bit G ve 5 bit B datası var. Bunları en kısa yoldan hızlı bir şekilde 8 bite çevirmek istesek, her birini 8 bitte sola dayayıp düşük değerli bitleri sıfır mı yapmak gerekir? Nasıl yapmak uygun olur?


bluekid

muhtemelen olmaz

5 bitte veya 6 bitte aldığınızı 8 bite yaymanız lazım
bir çeşit normalizasyon lazım yani




Mucit23

Oran kurarak olur belki ama çok yavaş olur. DMA2D bu işi nasıl yapıyor anlamış değilim. Bu konuya tekrar bakacağım şimdi başka bir sıkıntım var. 

Şuanda görüntüyü ekrana basmak için DCMI line kesmesini kullanıyorum.
void BSP_CAMERA_LineEventCallback(void)
{
  static uint32_t tmp, tmp2, counter;

  if(ysize > counter)
  {
    LCD_LL_ConvertLineToARGB8888((uint32_t *)(CAMERA_START_ADRES + tmp) , (uint32_t *)(LCD_FG_START_ADRES + tmp2));
    tmp  = tmp + xsize*sizeof(uint16_t);
    tmp2 = tmp2 + xsize*sizeof(uint32_t);
    counter++;
  }
  else
  {
    tmp = 0;
    tmp2 = 0;
    counter = 0;
  }
}


Çalışması ise şöyle; her bir satır kesmesi oluştuğunda o anki satırın verileri LCD_LL_ConvertLineToARGB8888 fonksiyonu ile DMA2D' ye gönderiliyor. DMA2D donanımı ise tümüyle o satırı ekrana gönderip geri geliyor.

Ben bu aktarım işlemini satır satır değilde Frame olarak yapmak istiyorum.

Line İnterrupt rutininin içeriğini sildim ardından frame interrupt rutinini aşağıdaki gibi yazdım.
void BSP_CAMERA_FrameEventCallback(void)
{
	uint32_t tmp=0, tmp2=0, counter=0;
  while(ysize>counter)
	{
    LCD_LL_ConvertLineToARGB8888((uint32_t *)(CAMERA_START_ADRES + tmp) , (uint32_t *)(LCD_FG_START_ADRES + tmp2));
    tmp  = tmp + xsize*sizeof(uint16_t);
    tmp2 = tmp2 + xsize*sizeof(uint32_t);
		counter++;
	}
}


kodlara bakarsanız mantık olarak aynı şekilde çalışıyor sadece while döngüsü içerisinde counter değerini ben arttırıyorum. Kodları yükleyip denediğimde ise sadece 1 frame basılıyor daha sonra yeni görüntü basılmıyor. Bu sırada kameradan veri geliyor işlemcide donmuyor hatta frame ve line kesmeleri de sekteye uğramadan oluşuyor. Ama sadece 1 frame gelip duruyor. Bu durumu çözmeye çalışıyorum sabahtan beri.

Benim amacım görüntüyü satır satır değilde frame frame basmak. Nasıl çözerim bu işi fikir yürütebilen var mı?

kimlenbu

şöyle bir işlem yapmışlar ama test etmedim, mantığını anlamaya da uğraşmadım :

http://forum.arduino.cc/index.php?topic=285303.0

Mucit23

#4
Onu deneyeceğim fakat önce şu frame işini çözmem lazım. Sizce neden 1 frame basılıp sonra duruyor?
ekleme
Önceki mesajımda en son verdiğim kod parçacığında while döngüsünün sayısı 50'nin üzerine çıkınca artık sistem çalışmıyor. Yarın DMA2D TC kesmesini aktif edip deneyeceğim.

Mucit23

Selamlar,

Elimde bir kamera var ve Kameranın image Array yapısı aşağıdaki gibi.



Eğer Kamera ve DMA düzgün çalışıyorsa(Öyle görünüyor) Kamera dan aldığım görüntü bu şekilde hafızada tutuluyor olması gerekir. Bu image arrayı bir şekilde RGB888 formatına dönüştürmem gerekiyor.

RGB sıralı gitmediği için bir mantık kuramadım. Belki STM32F7 de ki DMA2D donanımınının doğrudan bu formatı destekliyordur. Dökümanlarda doğrudan bilgi bulamadım.

Birkaç sorum olacak.

1-) RAW image dedikleri bu mudur?
2-) Pixel'leri RGB888 formatına çevirmek için nasıl bir yöntem izlenebilir?

Amacım Bu image arrayı LCD'de görüntüleyebilmek.

Teşekkürler.



Mucit23

Güncell

Bu konuda nasıl bir yöntem izleyebilirim. Hazır fonksiyonlar kütüphaneler varmıdır?

Karamel

Hocam merhaba. Sanirim sorun st nin camera unit i ile sizin camera module ciktilari uyusmuyor? Bu soruyu st microelectronics e sormamiz daha uygun olmazmi?  ??? Belki bu soruna ozel hardware bir cozum yapmislardir?

Mucit23

#8
Karamel sorun ST ile ilgili değil. Aslında ST ile ilgili birçok sorun var ama konu ile ilgili değil. Mesela şuan Aptinanın bir sensörüyle uğraşıyorum. Her nedense DCMI kesmelerini aktif edince DMA donanımı DCMI'dan sürekli 0xFFFFFFFF okuyor ve bunu hafızaya yazıyor. DCMI kesmeleri aktif olmayınca problem yok gibi. Bunu ST foruma yazsam bile tatmin edici cevaplar alamıyorum. Herneyse şuanda DMA TC kesmesi oluşuyor ve bayer formatta datalar alıyorum. Bu dataları nasıl pixel datalarına dönüştürebilirim? Bunu araştırıyorum. Tabi bu işli birde hızlı yapmam lazım.

Elektroemre

Bu dizilim Bayer pattern olarak geçiyor galiba.
STM32F746'nın datasheet'inin 42. DCMI'ın sayfasında raw bayer format'ı desteklediği yazıyor. TFT controller ya da DMA2D'de böyle bir ibare yok.
Kamera DCMI ile bağlıysa bu işi hardware halledebilir gibi duruyor. Diğer durumda dönüşüm sofware ile yapılmalı.
Kamera STM32'ye nasıl bağlı?

Mucit23

DCMI ile bağlı. Ama çok sorun yaşıyorum. Donanım henüz oturmuş değil. Elimde birde OV9655 varki onda hiçbir problem yok.

DCMI konusuna tekrar bir göz atayım eğer hardware yapılabiliyorsa mükemmel ötesi olur. Diğer türlü yazılımla yapmak baya külfetli olur.

garezza

Çevirme işini ilk söylediğin gibi yapabilirsin sorun çıkmaz. Bunu şuna dayanarak söylüyorum TFT LCD sürerken her renk için 0-7 olarak 8 pin ayrılmıştı bunu 565 ile sürmek için düşük pinlerini 0'a çekerek kullandım(sola dayadım yani) hiçbir problem yaratmadı. Sende de problem çıkmaz. Matematiksel olarakta aynı test edebilirsiniz.

Mucit23

Bayer RAW formatı hakkında birkaç sorum olacak.

Daha önce bahsetmiştim Aptinanın bir sensörü ile uğraşıyorum. DCMI üzerinde görüntüyü alıp DMA vasıtasıyla hafızada ayırmış olduğum bölgeye yazabiliyorum.

Kamerayı çalıştırınca istediğim çözünürlükte hafıza bölgesinde bir takım değerler geliyor. Ama bu değerlere henüz anlam veremedim. Doğrudan gelen dataları pixel değeri olarak kullanıp sonuç elde edilirmi bilmiyorum.

Esasında benim kameranın resim matrisi aşağıdaki gibi


Bu yapıya bayer raw data diyorlar.

Normalde Bayer RAW dataları araştırdığım kadarıyla monochrome pixel datalarından oluşuyor. Bu datalara "Demosaicing" işlemi ile interpolasyon denilen yumuşatma işlemi uygulanarak normal resim elde ediliyor.
Bu linkte biraz bahsedilmiş
http://adamhooper.com/blog/posts/186-how-cameras-work-interpolation

Aslında Bayer RAW to RGB işlemi bayağı zor. Bu yüzden Kamera ile fotoğraf çekip Debug esnasında dataları ram'den alıp matlap üzerinde işlem yapıyorum.
Şuanda pek bir sonuç elde edemedim. Ama dün Data yapısının Yukarıda verdiğim resimdeki gibi olduğunu varsayıp sadece Green dataları alıp ekrana bastığımda kameradaki hareketleri zorda olsa ekrandan seçebildiğimi farkettim. Mesela lensin önünde elimi oynattığımda görüntüde de hareketlenmeler oluyor. Kamera çalışıyor gibi. Bir şekilde görüntü geliyor.

Aslında RAW data hakkında anlamadıklarım var.

1-) Mesela Kameranın çözünürlüğünü 480x272'ye ayarladım. RAW datada ise dizilim G-R-G-R şeklinde, alt satırda B-G-B-G şeklinde gidiyor. Görüntünün genişliğini 480 pixel yaptığımda ilk satır için düşünürsek bu G-R-G-R değerlerin toplamı 480'mı oluyor. Aynısı satırlar içinde geçerli.

2-) Diğer bir sorum ise Görüntü çözünürlüğü ile ilgili. Kameradan görüntü çözünürlüğünü 480x272'ye ayarlıyorum. Kameradan gelen görüntünün boyutunun gerçekten ayarladığım kadar olduğunu nasıl anlarım?

3-) Raw dataları aldık diyelim. Hafızada yukarıda verildiği gibi ham bayer raw data var. Bu pixelleri uygun formatta ekrana bassam ne tür bir sonuç elde edilir?

1. ve 2. sorumun cevabını öğrenmem benim için çok önemli.

Teşekkürler.


kantirici

#13
4 pixelden bir RGB pixel datası elde edilebilir aslında. Resimdeki green-red,blue-green pixel datasını baz alarak (soldaki örnek);

iki adet green pixel değeri toplanıp ikiye bölünür ve bir pixelin green değeri bulunur ve red blue aynen alınır ve bir pixel için RGB değeri elde edilir.

Bu durumda kamera çözünürlüğü bir kenar uzunluğu dördün kartı kare seçilir. Pek verimli olmasa da denenebilir.

Mucit23

Evet aslında olabilir. Fakat normalde sadece yeşil pixelleri bassam da yeşil tabanlı bir görüntü elde etmezmiyim? Ben şuan ona uğraşıyorum.