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 << " " ; //每列数据用 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," ")); 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 }