1. 程式人生 > >OpenCV學習筆記 cv.Mat 與 .txt 檔案資料的讀寫操作

OpenCV學習筆記 cv.Mat 與 .txt 檔案資料的讀寫操作

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。

  1. #include <iostream>
  2. #include <fstream>
  3. #include <iterator>
  4. #include <vector>
  5. usingnamespace std;  
  6. /*---------------------------- 
  7.  * 功能 : 將 cv::Mat 資料寫入到 .txt 檔案 
  8.  *----------------------------
     
  9.  * 函式 : WriteData 
  10.  * 訪問 : public  
  11.  * 返回 : -1:開啟檔案失敗;0:寫入資料成功;1:矩陣為空 
  12.  * 
  13.  * 引數 : fileName    [in]    檔名 
  14.  * 引數 : matData [in]    矩陣資料 
  15.  */
  16. int WriteData(string fileName, cv::Mat& matData)  
  17. {  
  18.     int retVal = 0;  
  19.     // 開啟檔案
  20.     ofstream outFile(fileName.c_str(), ios_base::out);  //按新建或覆蓋方式寫入
  21.     if
     (!outFile.is_open())  
  22.     {  
  23.         cout << "開啟檔案失敗" << endl;   
  24.         retVal = -1;  
  25.         return (retVal);  
  26.     }  
  27.     // 檢查矩陣是否為空
  28.     if (matData.empty())  
  29.     {  
  30.         cout << "矩陣為空" << endl;   
  31.         retVal = 1;  
  32.         return (retVal);  
  33.     }  
  34.     // 寫入資料
  35.     for (int r = 0; r < matData.rows; r++)  
  36.     {  
  37.         for (int c = 0; c < matData.cols; c++)  
  38.         {  
  39.             uchar data = matData.at<uchar>(r,c);  //讀取資料,at<type> - type 是矩陣元素的具體資料格式
  40.             outFile << data << "\t" ;   //每列資料用 tab 隔開
  41.         }  
  42.         outFile << endl;  //換行
  43.     }  
  44.     return (retVal);  
  45. }  
  46. /*---------------------------- 
  47.  * 功能 : 從 .txt 檔案中讀入資料,儲存到 cv::Mat 矩陣 
  48.  *      - 預設按 float 格式讀入資料, 
  49.  *      - 如果沒有指定矩陣的行、列和通道數,則輸出的矩陣是單通道、N 行 1 列的 
  50.  *---------------------------- 
  51.  * 函式 : LoadData 
  52.  * 訪問 : public  
  53.  * 返回 : -1:開啟檔案失敗;0:按設定的矩陣引數讀取資料成功;1:按預設的矩陣引數讀取資料 
  54.  * 
  55.  * 引數 : fileName    [in]    檔名 
  56.  * 引數 : matData [out]   矩陣資料 
  57.  * 引數 : matRows [in]    矩陣行數,預設為 0 
  58.  * 引數 : matCols [in]    矩陣列數,預設為 0 
  59.  * 引數 : matChns [in]    矩陣通道數,預設為 0 
  60.  */
  61. int LoadData(string fileName, cv::Mat& matData, int matRows = 0, int matCols = 0, int matChns = 0)  
  62. {  
  63.     int retVal = 0;  
  64.     // 開啟檔案
  65.     ifstream inFile(fileName.c_str(), ios_base::in);  
  66.     if(!inFile.is_open())  
  67.     {  
  68.         cout << "讀取檔案失敗" << endl;  
  69.         retVal = -1;  
  70.         return (retVal);  
  71.     }  
  72.     // 載入資料
  73.     istream_iterator<float> begin(inFile);    //按 float 格式取檔案資料流的起始指標
  74.     istream_iterator<float> end;          //取檔案流的終止位置
  75.     vector<float> inData(begin,end);      //將檔案資料儲存至 std::vector 中
  76.     cv::Mat tmpMat = cv::Mat(inData);       //將資料由 std::vector 轉換為 cv::Mat
  77.     // 輸出到命令列視窗
  78.     //copy(vec.begin(),vec.end(),ostream_iterator<double>(cout,"\t")); 
  79.     // 檢查設定的矩陣尺寸和通道數
  80.     size_t dataLength = inData.size();  
  81.     //1.通道數
  82.     if (matChns == 0)  
  83.     {  
  84.         matChns = 1;  
  85.     }  
  86.     //2.行列數
  87.     if (matRows != 0 && matCols == 0)  
  88.     {  
  89.         matCols = dataLength / matChns / matRows;  
  90.     }   
  91.     elseif (matCols != 0 && matRows == 0)  
  92.     {  
  93.         matRows = dataLength / matChns / matCols;  
  94.     }  
  95.     elseif (matCols == 0 && matRows == 0)  
  96.     {  
  97.         matRows = dataLength / matChns;  
  98.         matCols = 1;  
  99.     }  
  100.     //3.資料總長度
  101.     if (dataLength != (matRows * matCols * matChns))  
  102.     {  
  103.         cout << "讀入的資料長度 不滿足 設定的矩陣尺寸與通道數要求,將按預設方式輸出矩陣!" << endl;  
  104.         retVal = 1;  
  105.         matChns = 1;  
  106.         matRows = dataLength;  
  107.     }   
  108.     // 將檔案資料儲存至輸出矩陣
  109.     matData = tmpMat.reshape(matChns, matRows).clone();  
  110.     return (retVal);  
  111. }