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

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM