OpenCV學習筆記 cv.Mat 與 .txt 檔案資料的讀寫操作
阿新 • • 發佈:2019-02-12
1、按OpenCV格式實現的 .txt 檔案讀寫
可以用 cvSave 和 cvLoad 實現,格式和 .xml/.yml 的差不多,不過如果專用與 OpenCV 的資料讀寫,還是用 .xml/.yml 檔案格式較好,我比較喜歡 .yml 格式,可讀性非常棒。
用 cvSave 和 cvLoad 讀寫 .txt 檔案,其實現方式和資料格式與 .yml 檔案基本一致。
例如:cvSave("camera_matrix.txt",camera_matrix); //儲存了 camera_matrix 的陣列頭以及和它所指的data(類似yml形式的檔案)
2、匯入/匯出其它程式的 .txt 檔案資料
可以用常規的 sprintf_s 和 fprintf_s 來實現,不過效率比較低,這裡介紹一種快捷易用的方法,利用了 std 的 steam 和 vector。
- #include <iostream>
- #include <fstream>
- #include <iterator>
- #include <vector>
- usingnamespace std;
- /*----------------------------
- * 功能 : 將 cv::Mat 資料寫入到 .txt 檔案
-
*----------------------------
- * 函式 : WriteData
- * 訪問 : public
- * 返回 : -1:開啟檔案失敗;0:寫入資料成功;1:矩陣為空
- *
- * 引數 : fileName [in] 檔名
- * 引數 : matData [in] 矩陣資料
- */
- int WriteData(string fileName, cv::Mat& matData)
- {
- int retVal = 0;
- // 開啟檔案
- ofstream outFile(fileName.c_str(), ios_base::out); //按新建或覆蓋方式寫入
-
if
- {
- cout << "開啟檔案失敗" << endl;
- retVal = -1;
- return (retVal);
- }
- // 檢查矩陣是否為空
- if (matData.empty())
- {
- cout << "矩陣為空" << endl;
- retVal = 1;
- return (retVal);
- }
- // 寫入資料
- for (int r = 0; r < matData.rows; r++)
- {
- for (int c = 0; c < matData.cols; c++)
- {
- uchar data = matData.at<uchar>(r,c); //讀取資料,at<type> - type 是矩陣元素的具體資料格式
- outFile << data << "\t" ; //每列資料用 tab 隔開
- }
- outFile << endl; //換行
- }
- return (retVal);
- }
- /*----------------------------
- * 功能 : 從 .txt 檔案中讀入資料,儲存到 cv::Mat 矩陣
- * - 預設按 float 格式讀入資料,
- * - 如果沒有指定矩陣的行、列和通道數,則輸出的矩陣是單通道、N 行 1 列的
- *----------------------------
- * 函式 : LoadData
- * 訪問 : public
- * 返回 : -1:開啟檔案失敗;0:按設定的矩陣引數讀取資料成功;1:按預設的矩陣引數讀取資料
- *
- * 引數 : fileName [in] 檔名
- * 引數 : matData [out] 矩陣資料
- * 引數 : matRows [in] 矩陣行數,預設為 0
- * 引數 : matCols [in] 矩陣列數,預設為 0
- * 引數 : matChns [in] 矩陣通道數,預設為 0
- */
- int LoadData(string fileName, cv::Mat& matData, int matRows = 0, int matCols = 0, int matChns = 0)
- {
- int retVal = 0;
- // 開啟檔案
- ifstream inFile(fileName.c_str(), ios_base::in);
- if(!inFile.is_open())
- {
- cout << "讀取檔案失敗" << endl;
- retVal = -1;
- return (retVal);
- }
- // 載入資料
- istream_iterator<float> begin(inFile); //按 float 格式取檔案資料流的起始指標
- istream_iterator<float> end; //取檔案流的終止位置
- vector<float> inData(begin,end); //將檔案資料儲存至 std::vector 中
- cv::Mat tmpMat = cv::Mat(inData); //將資料由 std::vector 轉換為 cv::Mat
- // 輸出到命令列視窗
- //copy(vec.begin(),vec.end(),ostream_iterator<double>(cout,"\t"));
- // 檢查設定的矩陣尺寸和通道數
- size_t dataLength = inData.size();
- //1.通道數
- if (matChns == 0)
- {
- matChns = 1;
- }
- //2.行列數
- if (matRows != 0 && matCols == 0)
- {
- matCols = dataLength / matChns / matRows;
- }
- elseif (matCols != 0 && matRows == 0)
- {
- matRows = dataLength / matChns / matCols;
- }
- elseif (matCols == 0 && matRows == 0)
- {
- matRows = dataLength / matChns;
- matCols = 1;
- }
- //3.資料總長度
- if (dataLength != (matRows * matCols * matChns))
- {
- cout << "讀入的資料長度 不滿足 設定的矩陣尺寸與通道數要求,將按預設方式輸出矩陣!" << endl;
- retVal = 1;
- matChns = 1;
- matRows = dataLength;
- }
- // 將檔案資料儲存至輸出矩陣
- matData = tmpMat.reshape(matChns, matRows).clone();
- return (retVal);
- }