cv.Mat 与 .txt 文件数据的读写操作

来源:互联网 发布:核函数 知乎 编辑:程序博客网 时间:2024/05/16 18:57

来源:http://blog.csdn.net/chenyusiyuan/article/details/7974378#comments

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。

 

[cpp] view plaincopy
  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. }