2012-09-09 128 views
0

使用OpenCV。OpenCV - 顏色校正

我有一個RGB圖像,每個值是一個浮點數。 我也有一個標準的色彩校正矩陣3x4。

什麼是最快方式'應用'這個矩陣的圖像?

如果你不知道顏色校正...這是一個簡單的矩陣運算。

如果圖像看起來像這樣(每一像素爲3個浮子):

R G B 
R G B 
R G B 
R G B 
R G B 
. 
. 
. 

然後我想執行以下操作:

1 R G B  [ A1, A2, A3 ] 
1 R G B  [ R1, R2, R3 ] 
1 R G B * [ G1, G2, G3 ] 
1 R G B  [ B1, B2, B3 ] 
1 R G B 
. 
. 
. 

所有在3×4矩陣值是常數。

謝謝。

+0

我不明白。你有rgb,你想要一個rgba嗎?或者你想讓矩陣看到一個rgb,並帶有rgb結果?通常情況下,轉換(我認爲)會給你最快的倍數,因爲它已經過優化。甚至不得不增加開銷以將顏色CV_BGR2RGBA(再加上1.0複製到新的alpha),它仍然可能比手寫矢量化代碼更快。 –

+0

'A'不是Alpha通道,只是一個const乘以1,所以它被添加 – Gilad

回答

1

乘以顏色校正矩陣的RGB部分:

transform(imageIn,imageOut,M3x3); 

然後在信道校正補充:

add(imageOut,Scalar(A1,A2,A3),imageOut); 

閱讀在opencv2refman 約變換它意味着你可以使用

transfrom(imageIn,imageOut,M4X3); 

得到相同的結果我n一步(它確實是dst(I)= mtx·[src(I); 1],非常有幫助),避免必須添加A組件。 你的赦免,如果這應該是一個M3X4。當涉及到矩陣數學,行數與列數以及哪一個先出現時,我的閱讀困難很多。

+0

感謝你的回答,你能解釋一下這是如何完成的,因爲我不熟悉變換(這是CvMul?)。我使用一個Image對象,在執行此操作之前是否需要重新塑造它? – Gilad

+1

我懷疑cv :: transform可能是一個很好的'你有沒有讀過 - 所有的文檔?家庭作業問題,因爲它(對我而言)隱藏在opencv2refman中一堆RNG和SVD描述下面。我又回去讀了一遍,嘿,瞭望!它應該用一個4X3矩陣完全符合你的要求。 –

+0

@Gilad有關如何將圖像放入Mat中的詳細信息超出了您的問題範圍,並且非常基礎的openCV。您應該接受這個答案,因爲它是將顏色校正矩陣應用於openCV中圖像的最快方法。 –

0

如果您確定矩陣中的值存儲在RGB中(默認情況下,OpenCV在BGR模式下讀取它們),則可以繼續進行簡單的矩陣多重定位。您只需創建包含您指定的RGB值的右矩陣,即 1,R,G,B 1,R,G,B,...,原始圖像中每像素1行

這裏是你如何做(用C++)

// say img is your original RGB matrix, transform is your transformation matrix 

std::vector<cv::Mat> channels; 
// this extracts the R,G and B channels in single matrices 
cv::split(img, channels); 
// create a matrix on ones in floating point 
cv::Mat oneMat = cv::Mat::ones(img.size(), CV_32F); 
oneMat.push_front(channels); 
// now channels is a vector containing 4 matrices of the same dimension as img 
// you want to group those matrix into 1 single matrix of same dimension and 4 channels 
// 1, R, G, B 
cv::Mat rgbOne; 
cv::merge(channels, rgbOne); 
// Transform the row by col, 4 channel matrix rgbOne into a row*col, 4, single channel matrix prior to multiplication 
cv::Mat reshaped = rgbOne.reshape(1, rgbOne.rows*rgbOne.cols); 
// reshape is very fast as no allocation is required, check documentation 

// now simply do the matrix multiplication 
cv::Mat colorCorrectedImage = reshaped*transform; 

// get back colorCorrectedImage to it's original dimensions 
cv::Mat colorCoorectedReshaped = colorCorrectedImage.reshape(4, rgbOne.rows); 
// note that you still have the extra channel of ones 
// you can use split and merge functions as above to get rid of it and get your proper RGB image 
+0

謝謝。似乎在重新安排數據方面有相當多的操作,所以我有一種感覺,它會工作得很慢,但我會測試它。 – Gilad

+0

最長的操作應該是矩陣乘法,大多數其他操作應該非常快。重塑是O(1),拆分和合並涉及將數值從一個數組複製到另一個數組,但這非常快。你必須檢查數學,但Bobbi的答案也可以完成這項工作,並且應該更快,因爲它直接對數據進行操作而不必修改它。這是兩行代碼!以前從未使用過變換函數,但一定會記住它。 – remi