2014-01-13 55 views
1

我有一個3通道的矩陣,我有一個訪問和更改元素值的問題。我有這樣的代碼:opencv矩陣多通道訪問和填充

Mat m(4,4, CV_8UC3); 
Vec3b a; 
a[0] = 255; 
a[1] = 0; 
a[2] = 0; 
m.at<Vec3b>(0,0) = a; 

當我打印的矩陣m,我有這樣的:

[255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] 

這是很好的,但是當我矩陣存儲與imwrite我得到的圖像是這個:

enter image description here

,我不明白爲什麼它是藍色的,爲什麼我有一個方形的2x2藍色的,我應該只有第一像素的紅色不是嗎?

我在某個地方犯過一個錯誤嗎?

回答

0

正如前面提到的,像素高亮度像素旁邊,因爲JPEG是一種有損算法取後JPG壓縮非零值。實際上,JPEG壓縮在具有強梯度的圖像區域中精確丟棄信息。

至於第二個問題:您的像素,因爲一個opencv的夸克的是藍色:顏色通道不存儲在R,G,B的順序,但在B,G,R的順序:

對於彩色圖像,渠道訂貨通常是藍色,綠色,紅色

來源:http://docs.opencv.org/modules/core/doc/drawing_functions.html?highlight=green

(這是那些東西,使生活苦不堪言OpenCV的程序員之一)

+0

這不是OpenCV怪癖,但Windows怪癖。如果按原樣(如bmp或ppm)將3通道圖像緩衝區寫入磁盤並在某個圖片瀏覽器中打開它,則會看到它被視爲BGR圖像而不是RGB圖像。OpenCV使用RGB格式的圖像意味着交換每個imread和imwrite的圖像像素。在很多情況下這只是浪費時間。 –

+0

好的,所以這是一個BMP和PPM的怪癖,成爲Opencv怪癖:)你碰巧知道像素在保存/閱讀JPG或PNG時是否交換? –

+0

BMP和PPM只是存儲圖像緩衝區的格式示例,沒有任何類型的壓縮。如果您爲映像分配了1 MB內存並將其存儲在硬盤上,則硬盤上將佔用1兆字節。 PNG或JPEG並非如此。這些圖像將更小,這意味着它們被壓縮(PNG無損壓縮和JPG有損壓縮)。因此,關於交換的問題是毫無意義的,因爲這些格式不是存儲像素值,而是可以從中恢復這些值的數據。 –

3

我不明白爲什麼它是藍色的......不是紅色的?

在OpenCV中,圖像格式由創建圖像時的標誌設置,例如, CV_8UC3表示8位像素,無符號3色通道。在彩色圖像中,像素順序爲BGR,數據按行順序存儲。同樣,BGRACV_8UC4。所以你設定的值是藍色而不是紅色,這就是你變藍的原因。

我應該只有第一個像素...?

原因是,對於壓縮圖像類型,例如, JPG,他們不能保證精確保留內容。嘗試將imwrite()設爲未壓縮的例如BMP圖片(通常)。你會得到像這樣的:

enter image description here

+0

非常感謝你!有用!但我不明白爲什麼? Jpg不好? – Ekica

+1

'JPG'是一種壓縮圖像類型,它不會始終保持內容的精確。 – herohuyongtao

+0

謝謝你的解釋! :) – Ekica