
Q1.有些人可能會問,這樣交錯算出的影像未必是最真實的,為什麼不採用每個點去接收RGB然後得出一個影像?
A1:基於成本考量,除非很特殊的光學設計,不然在一個面積有限sensor面積裡同時感測出不同顏色的光是有困難的,總不能在sensor上面裝個機械的濾淨閘快速的替換濾淨,利用高frame rate讓RGB影像幾乎是同一個時間點,當然這種設計相對難度高且成本也會高出許多。所以近代的消費性sensor幾乎都會提出這樣交錯有規則性的pattern感測顏色。
Q2.為什麼Bayer pattern 綠色的點較多?
A2:有一句話叫做科技來自於人性,camera sensor拍出來的影像始終是要給消費者看的,所以才會有I phone拍出來的影像怎麼比小米好的感覺,一方面是sensor的成本反映出的sensitivity不同,另一方面就是影像教調的部分。回到原來的問題,經科學證實人眼對於綠色較為敏感,故綠色在Bayer pattern的設計也有考慮到這點,採取2x2綠色佔較高權重的RGGB、BGGR,而各家大廠為了去彌補這樣的問題,有的在sensor接收過後的影像做調教(各種Interpolation色彩轉換),有的則是在sensor濾鏡上做設計,配合各家色彩轉換的強項提出屬於各家廠商特有的pattern 濾鏡。
[補記 2016/07/16]
最近無意間在網頁上瀏覽到小米5的簡介,簡介中附錄了一張小米5照相機的結構圖,
實在畫的太好非常適合踏入這個領域初學者示意講解,
(以下圖檔純為教學解釋用,並無其餘商業用途,版權為小米所有)
以上為一個現代相機模組的示意圖,由左而右為多片鏡片+彩色濾淨組合成,
其次為它的外殼,藍色面板為camera sensor,可透過camera sensor 取的Raw data,
故上圖示意camera sensor後面有一塊RGGB的圖案,即為本章節介紹 Color pattern的轉換,
最後後面有個ISP(Image Signal Processing),專門負責對這顆camera sensor下指令,
來做曝光(AE) 對焦(AG) 白平衡(AWE)與色彩平衡的控制。
對於現代消費性電子來說,近幾代camera sensor大廠都已提供的這樣外加ISP模組架構流程做應用,甚至有些camera sensor本身就不提供3A功能,純粹給應用端自行調配設計。
這也就是上面我說即使手機使用一樣的sensor,但為什麼拍出來會有不一樣的感覺。
此篇提供了一個簡單的3x3 Interpolation協助Bayer pattern做色彩轉換,大致可分為中心點為R與B兩種,與中心點為綠色不同周遭不同排列的G1、G2兩種。
透過分析可將Bayer pattern 橫向縱向積偶排列組合分成四種,正好符合以上3x3interpolation的核心原則,但建議coding的人還是要注意一下,sensor左上角的起始是RGGB or BGGR? 若情況反過來有可能就會做出一格一格的馬賽克效果。
#define B_OFFSET 0 #define G_OFFSET 1 #define R_OFFSET 2 #define ODD(i) ((i)&1) #define EVEN(i) (!((i)&1)) void BayerConversion(unsigned char *rawData, unsigned char *dst, int dst_w, int dst_h, int rawData_w) { int x,y; int yWidth=0, yRawWidth=0, ym1RawWidth = 0, yp1RawWidth; int pix; int Red,Green,Blue; memset(dst,0,sizeof(unsigned char)*dst_w*dst_h*3); for (y = 1; y < dst_h - 1; y++) { yWidth += dst_w; yRawWidth += rawData_w; ym1RawWidth = yRawWidth - rawData_w; yp1RawWidth = yRawWidth + rawData_w; for (x = 1; x < dst_w - 1; x++) { pix = ((x+yWidth)<<2); if (ODD(y)) if (ODD(x)) { Blue = ((rawData[x-1+ yRawWidth] + rawData[x+1+ yRawWidth]) >> 1); Green = rawData[x + yRawWidth]; Red = ((rawData[x +ym1RawWidth] + rawData[x +yp1RawWidth]) >> 1); } else { // ODD(y) EVEN(x) Blue = rawData[x + yRawWidth]; Green = ((rawData[x-1+ yRawWidth] + rawData[x+1+ yRawWidth] + rawData[x +ym1RawWidth] + rawData[x +yp1RawWidth]) >> 2); Red = ((rawData[x-1+ym1RawWidth] + rawData[x+1+ym1RawWidth] + rawData[x-1+yp1RawWidth] + rawData[x+1+yp1RawWidth]) >> 2); } else if (ODD(x)) { // EVEN(y) ODD(x) Blue = ((rawData[x-1+ym1RawWidth] + rawData[x+1+ym1RawWidth] + rawData[x-1+yp1RawWidth] + rawData[x+1+yp1RawWidth]) >> 2); Green = ((rawData[x-1+ yRawWidth] + rawData[x+1+ yRawWidth] + rawData[x +ym1RawWidth] + rawData[x +yp1RawWidth]) >> 2); Red = rawData[x + yRawWidth]; } else { //EVEN(y) EVEN(x) Blue = ((rawData[x +ym1RawWidth] + rawData[x +yp1RawWidth]) >> 1); Green = rawData[x + yRawWidth]; Red = ((rawData[x-1+ yRawWidth] + rawData[x+1+ yRawWidth]) >> 1); } dst[pix+B_OFFSET] = Red; dst[pix+G_OFFSET] = Green; dst[pix+G_OFFSET] = Blue; } } }
沒有留言:
張貼留言