如果我們想把OpenCV中的矩陣數據類型cv::Mat保存在一個文件中,可以使用如下的代碼:
void writeMatToFile(cv::Mat& m, const char* filename) { ofstream fout(filename); if(!fout) { cout<<"File Not Opened"<<endl; return; } fout << m; fout.close(); }
上述代碼生成的數據由中括號括起來了,我們如果想導入Matlab做進一步處理的話,最好去掉首尾的中括號,當然,我們可以打開txt,手動刪除中括號。如果我們想偷懶,讓程序來刪除的話,可以使用如下的代碼:
void writeMatToFile(cv::Mat& m, const char* filename) { ofstream fout(filename); if(!fout) { cout<<"File Not Opened"<<endl; return; } //fout << m.rows << " " << m.cols << " " << m.dims << endl; fout << m; fout.close(); // Delete the begining '[' and ending ']' fstream file(filename); string line; int cnt = 0; fout.open("tmp.txt"); while (!file.eof()) { getline(file, line); if (cnt == 0) line = line.substr(1); // Delete '[' if (cnt == m.rows - 1) line.pop_back(); // Delete ']' fout << line << endl; ++cnt; } file.close(); fout.close(); file.open("tmp.txt"); fout.open(filename); while (!file.eof()) { getline(file, line); fout << line << endl; } file.close(); fout.close(); system("del tmp.txt"); }
還有一種方法用for循環將每個位置的數據寫入文本中,但是這種方法保存下來的值跟上面那種方法稍有些出入,上述方法精度應該更高一些,我也把這種方法列出來作為參考吧:
void writeMatToFile(cv::Mat& m, const char* filename) { ofstream fout(filename); if(!fout) { cout<<"File Not Opened"<<endl; return; } for (int i = 0; i < m.rows; ++i) { for (int j = 0; j < m.cols; ++j) { for (int k = 0; k < m.channels(); ++k) { fout << m.at<float>(i, j * m.channels() + k); if (j * m.channels() + k < m.cols * m.channels() - 1) { fout << ", "; } } } if (i < m.rows - 1) fout << "; " << endl; } fout.close(); }
我們也可以用OpenCV自帶的API來完成數據的讀和寫,我們來看CvMat數據類型的讀和寫,關於CvMat和cv::Mat之間的轉換請猛戳這里:
// Save CvMat to .xml file CvMat *m = cvLoadImageM("image.jpg", CV_LOAD_IMAGE_COLOR); cvSave("m.yml", m); // Save cv::Mat to .xml file cv::Mat m; CvMat cm = m; cvSave("cm.yml", &cm); // Load .xml file to CvMat CvFileStorage *fs = cvOpenFileStorage("m.yml", 0, CV_STORAGE_READ); CvMat *newM = (CvMat*) cvLoad("m.yml");