2013-07-18 284 views
4

我正在使用的程序是讀取一些位圖,並期待32FC1圖像。OpenCV保存CV_32FC1圖像

我想創建這些圖像

cv::Mat M1(255, 255, CV_32FC1, cv::Scalar(0,0,0)); 
cv::imwrite("my_bitmap.bmp", M1); 

,但是當我檢查的深度 - 它始終是CV_8U

如何創建的文件,以便它們將包含正確的信息?

更新:如果我使用不同的文件擴展名 - 例如tif或png

我正在閱讀 - 使用已實施的代碼 - 與cvLoadImage

我想創建現有的代碼 - 檢查圖像類型 - 可以使用的文件。

我無法轉換現有代碼中的文件。現有的代碼不會嘗試讀取隨機圖像類型並將其轉換爲所需的類型,但會檢查文件是否爲所需的類型。

我發現了 - 謝謝你的答案 - cv :: imwrite只寫整型圖像。

是否有另一種方法 - 使用OpenCV或其他方式 - 寫入圖像,以便我最終與CV_32F類型?

再次更新: 代碼讀取圖片...如果成CV ::墊:

cv::Mat x = cv::imread(x_files, CV_LOAD_IMAGE_ANYDEPTH|CV_LOAD_IMAGE_ANYCOLOR); 

現有代碼:

IplImage *I = cvLoadImage(x_files.c_str(), CV_LOAD_IMAGE_ANYDEPTH|CV_LOAD_IMAGE_ANYCOLOR); 
+0

你給你的外部程序是什麼?該文件或'cv :: Mat'對象的路徑? – Jacob

+0

我們可以看到使用cvLoadImage讀取文件的代碼嗎? – Bull

+0

我給它的文件路徑 – Thalia

回答

2

您的問題是位圖商店內部整數數據不會浮動。如果保存時問題出現四捨五入錯誤,則需要使用不同的文件格式,或者在保存前縮放數據,然後在保存後再縮小。如果您只是想將讀取文件後得到的矩陣轉換爲浮點數,則可以使用cv :: convertto

+0

不幸的是,我不能在閱讀後轉換類型,圖像必須是正確的類型。在寫入之前,我嘗試了文件格式和縮放...然後從文檔中發現,只寫入CV_8U。有其他選擇嗎? – Thalia

+0

出於好奇,爲什麼你不能在閱讀後轉換類型?取決於你需要的精度,如果你有一套已知的數值,你可以將你的圖像乘以一些常數(比如說100),把它保存爲16位PNG,然後當你讀回數字時除以100.甚至需要改變類型雖然。 – Hammer

3

cv::imwrite() .bmp編碼器假設爲8位通道。

如果您只需要使用OpenCV編寫.bmp文件,則可以將32FC1圖像轉換爲8UC4,然後使用cv::imwrite()編寫它,您將獲得每像素32位的.bmp文件。 我猜你讀取文件的程序會將32位像素解釋爲32FC1。 .bmp format沒有明確的通道結構,只是每個像素的位數。因此,您應該能夠在OpenCV中將32位像素寫爲8通道的4通道,並在另一個程序中將它們作爲單通道32位像素讀取 - 如果您這樣做,您需要了解讀者的字節序假設。成纔像下面應該工作:

cv::Mat m1(rows, cols, CV_32FC1); 
... // fill m1 
cv::Mat m2(rows, cols, CV_8UC4, m1.data); // provide different view of m1 data 
// depending on endianess of reader, you may need to swap byte order of m2 pixels 
cv::imwrite("my_bitmap.bmp", m2); 

您將無法正確讀取你在OpenCV中創建的文件,因爲在OpenCV中的.BMP解碼器假定該文件是1位或8位數據的3個信道(即它不能讀取32位像素)。


編輯

可能是一個更好的選擇是使用OpenEXR格式,其OpenCV的編解碼器。我假設你只需要用.exr擴展名保存你的文件。

+0

謝謝,我不知道imwrite總是創建CV_8U。請參閱更新。即使我在寫作之前進行了轉換,我仍然可以獲得CV_8U(根據文檔)。所以......我的情況是絕望的嗎?或者有什麼方法可以創建這些圖像? – Thalia

+0

你有讀取.bmp文件的程序的源代碼嗎?我想知道它對像素格式的假設。 – Bull