2012-05-01 143 views
10

我試圖使用OpenCV 2.3.1將12位拜耳圖像轉換爲8位RGB圖像。這似乎是它應該使用cvCvtColor功能是相當簡單,但功能拋出時,我把它叫做這個代碼的異常:使用OpenCV將12位拜耳圖像轉換爲8位RGB

int cvType = CV_MAKETYPE(CV_16U, 1); 
cv::Mat bayerSource(height, width, cvType, sourceBuffer); 
cv::Mat rgbDest(height, width, CV_8UC3); 
cvCvtColor(&bayerSource, &rgbDest, CV_BayerBG2RGB); 

我以爲我跑過去sourceBuffer結束,由於輸入數據是12位的,我不得不通過16位類型,因爲OpenCV沒有12位類型。所以我把寬度和高度除以2,但cvCvtColor仍然拋出一個沒有任何有用信息的異常(錯誤信息是「未知異常」)。

有一個similar question幾個月前發佈,這是從來沒有回答,但由於我的問題更具體地處理12位拜耳數據,我認爲這是非常明顯的值得一個新的問題。

在此先感謝。

編輯:我一定是失去了一些東西,因爲我甚至無法獲得cvCvtColor的函數,在8位數據的工作:

cv::Mat srcMat(100, 100, CV_8UC3); 
const cv::Scalar val(255,0,0); 
srcMat.setTo(val); 
cv::Mat destMat(100, 100, CV_8UC3); 
cvCvtColor(&srcMat, &destMat, CV_RGB2BGR); 
+2

所以,事實證明,我*爲*失去了一些東西。我的同事指出我正在混合使用C和C++調用。將最後一行更改爲 cv :: cvtColor(srcMat,destMat,CV_RGB2BGR); 使一切工作像一個魅力。我仍在研究將16位拜耳數據轉換爲8位RGB數據的原始問題,因此如果我找到了答案,我會發布更新。 – Gillfish

+2

'cvCvtColor'屬於舊的C OpenCV API,但'cv :: Mat'是C++ API中的一個類。混合它們不是一個好主意,你最好只使用一個版本的API。 'cv :: cvtColor(srcMat,dstMat,COLOR_RGB2BGR)'應該適合你。 –

+0

「綠色過濾器外觀」可能意味着您指定了錯誤的拜耳模式。嘗試一切。 – user3443369

回答

3

Gillfish的答案在技術上可行,但在轉換期間它使用比輸入(它是CV_16UC1)更小的數據結構(CV_8UC1)並丟失一些顏色信息。

我建議首先解碼拜耳編碼,但保持每通道16位(從CV_16UC1到CV_16UC3),然後轉換爲CV_8UC3。

修改後的Gillfish的代碼(假設攝影機給出了16位編碼拜耳圖像):

// Copy the data into an OpenCV Mat structure 
cv::Mat mat16uc1_bayer(height, width, CV_16UC1, inputBuffer); 

// Decode the Bayer data to RGB but keep using 16 bits per channel 
cv::Mat mat16uc3_rgb(width, height, CV_16UC3); 
cv::cvtColor(mat16uc1_bayer, mat16uc3_rgb, cv::COLOR_BayerGR2RGB); 

// Convert the 16-bit per channel RGB image to 8-bit per channel 
cv::Mat mat8uc3_rgb(width, height, CV_8UC3); 
mat16uc3_rgb.convertTo(mat8uc3_rgb, CV_8UC3, 1.0/256); //this could be perhaps done more effectively by cropping bits 
14

我能我的數據轉換爲8位RGB使用以下代碼:

// Copy the data into an OpenCV Mat structure 
cv::Mat bayer16BitMat(height, width, CV_16UC1, inputBuffer); 

// Convert the Bayer data from 16-bit to to 8-bit 
cv::Mat bayer8BitMat = bayer16BitMat.clone(); 
// The 3rd parameter here scales the data by 1/16 so that it fits in 8 bits. 
// Without it, convertTo() just seems to chop off the high order bits. 
bayer8BitMat.convertTo(bayer8BitMat, CV_8UC1, 0.0625); 

// Convert the Bayer data to 8-bit RGB 
cv::Mat rgb8BitMat(height, width, CV_8UC3); 
cv::cvtColor(bayer8Bit, rgb8BitMat, CV_BayerGR2RGB); 

我曾誤假定12位數據我是從照相機獲得被緊密填充,從而使2個12位值中包含的3個字節。事實證明,每個值都包含在2個字節中,所以我不必進行任何解包就可以將我的數據轉換爲OpenCV支持的16位數組。

編輯:查看@ petr的改進答案,在轉換爲8位之前轉換爲RGB,以避免在轉換過程中丟失任何顏色信息。

+0

我在這裏做的和這裏一樣,但是我的圖像似乎在圖像的頂部有一個綠色濾鏡。不知道爲什麼 –

+0

@pksorensen:如果您有相關問題,只需在新問題中提問並將其鏈接回此問題即可。這樣你可以添加更多關於你的特定問題的細節。 – Gillfish

+0

我最終採取了不同的道路,並使用尼康SDK做脫鉤者,因爲我遇到了一些問題,試圖用libraw和opencv來做。使用nikons SDK給了我更好的結果,並找出爲什麼用libraw無法實現相同的結果,opencv必須等待。不管怎麼說,還是要謝謝你。 –