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

所属分类: 软件编程 / C 语言 阅读数: 101
收藏 0 赞 0 分享

本篇文章主要介绍了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。

#include <iostream> 
#include <fstream> 
#include <iterator> 
#include <vector> 
 
using namespace std; 
 
/*---------------------------- 
 * 功能 : 将 cv::Mat 数据写入到 .txt 文件 
 *---------------------------- 
 * 函数 : WriteData 
 * 访问 : public 
 * 返回 : -1:打开文件失败;0:写入数据成功;1:矩阵为空 
 * 
 * 参数 : fileName [in] 文件名 
 * 参数 : matData [in] 矩阵数据 
 */ 
int WriteData(string fileName, cv::Mat& matData) 
{ 
 int retVal = 0; 
 
 // 打开文件 
 ofstream outFile(fileName.c_str(), ios_base::out); //按新建或覆盖方式写入 
 if (!outFile.is_open()) 
 { 
 cout << "打开文件失败" << endl; 
 retVal = -1; 
 return (retVal); 
 } 
 
 // 检查矩阵是否为空 
 if (matData.empty()) 
 { 
 cout << "矩阵为空" << endl; 
 retVal = 1; 
 return (retVal); 
 } 
 
 // 写入数据 
 for (int r = 0; r < matData.rows; r++) 
 { 
 for (int c = 0; c < matData.cols; c++) 
 { 
 uchar data = matData.at<uchar>(r,c); //读取数据,at<type> - type 是矩阵元素的具体数据格式 
 outFile << data << "\t" ; //每列数据用 tab 隔开 
 } 
 outFile << endl; //换行 
 } 
 
 return (retVal); 
} 
 
 /*---------------------------- 
 * 功能 : 从 .txt 文件中读入数据,保存到 cv::Mat 矩阵 
 * - 默认按 float 格式读入数据, 
 * - 如果没有指定矩阵的行、列和通道数,则输出的矩阵是单通道、N 行 1 列的 
 *---------------------------- 
 * 函数 : LoadData 
 * 访问 : public 
 * 返回 : -1:打开文件失败;0:按设定的矩阵参数读取数据成功;1:按默认的矩阵参数读取数据 
 * 
 * 参数 : fileName [in] 文件名 
 * 参数 : matData [out] 矩阵数据 
 * 参数 : matRows [in] 矩阵行数,默认为 0 
 * 参数 : matCols [in] 矩阵列数,默认为 0 
 * 参数 : matChns [in] 矩阵通道数,默认为 0 
 */ 
int LoadData(string fileName, cv::Mat& matData, int matRows = 0, int matCols = 0, int matChns = 0) 
{ 
 int retVal = 0; 
 
 // 打开文件 
 ifstream inFile(fileName.c_str(), ios_base::in); 
 if(!inFile.is_open()) 
 { 
 cout << "读取文件失败" << endl; 
 retVal = -1; 
 return (retVal); 
 } 
 
 // 载入数据 
 istream_iterator<float> begin(inFile); //按 float 格式取文件数据流的起始指针 
 istream_iterator<float> end; //取文件流的终止位置 
 vector<float> inData(begin,end); //将文件数据保存至 std::vector 中 
 cv::Mat tmpMat = cv::Mat(inData); //将数据由 std::vector 转换为 cv::Mat 
 
 // 输出到命令行窗口 
 //copy(vec.begin(),vec.end(),ostream_iterator<double>(cout,"\t")); 
 
 // 检查设定的矩阵尺寸和通道数 
 size_t dataLength = inData.size(); 
 //1.通道数 
 if (matChns == 0) 
 { 
 matChns = 1; 
 } 
 //2.行列数 
 if (matRows != 0 && matCols == 0) 
 { 
 matCols = dataLength / matChns / matRows; 
 } 
 else if (matCols != 0 && matRows == 0) 
 { 
 matRows = dataLength / matChns / matCols; 
 } 
 else if (matCols == 0 && matRows == 0) 
 { 
 matRows = dataLength / matChns; 
 matCols = 1; 
 } 
 //3.数据总长度 
 if (dataLength != (matRows * matCols * matChns)) 
 { 
 cout << "读入的数据长度 不满足 设定的矩阵尺寸与通道数要求,将按默认方式输出矩阵!" << endl; 
 retVal = 1; 
 matChns = 1; 
 matRows = dataLength; 
 } 
 
 // 将文件数据保存至输出矩阵 
 matData = tmpMat.reshape(matChns, matRows).clone(); 
 
 return (retVal); 
} 

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

更多精彩内容其他人还在看

用标准c++实现string与各种类型之间的转换

这个类在头文件中定义, < sstream>库定义了三种类:istringstream、ostringstream和stringstream,分别用来进行流的输入、输出和输入输出操作。另外,每个类都有一个对应的宽字符集版本
收藏 0 赞 0 分享

C++如何通过ostringstream实现任意类型转string

再使用整型转string的时候感觉有点棘手,因为itoa不是标准C里面的,而且即便是有itoa,其他类型转string不是很方便。后来去网上找了一下,发现有一个好方法
收藏 0 赞 0 分享

C/C++指针小结

要搞清一个指针需要搞清指针的四方面的内容:指针的类型,指针所指向的类型,指针的值或者叫指针所指向的内存区,还有指针本身所占据的内存区
收藏 0 赞 0 分享

C++ 类的静态成员深入解析

在C++中类的静态成员变量和静态成员函数是个容易出错的地方,本文先通过几个例子来总结静态成员变量和成员函数使用规则,再给出一个实例来加深印象
收藏 0 赞 0 分享

C++类的静态成员初始化详细讲解

通常静态数据成员在类声明中声明,在包含类方法的文件中初始化.初始化时使用作用域操作符来指出静态成员所属的类.但如果静态成员是整型或是枚举型const,则可以在类声明中初始化
收藏 0 赞 0 分享

C++类静态成员与类静态成员函数详解

静态成员不可在类体内进行赋值,因为它是被所有该类的对象所共享的。你在一个对象里给它赋值,其他对象里的该成员也会发生变化。为了避免混乱,所以不可在类体内进行赋值
收藏 0 赞 0 分享

C++中的friend友元函数详细解析

友元可以是一个函数,该函数被称为友元函数;友元也可以是一个类,该类被称为友元类。友元函数的特点是能够访问类中的私有成员的非成员函数。友元函数从语法上看,它与普通函数一样,即在定义上和调用上与普通函数一样
收藏 0 赞 0 分享

static全局变量与普通的全局变量的区别详细解析

以下是对static全局变量与普通的全局变量的区别进行了详细的分析介绍,需要的朋友可以过来参考下,希望对大家有所帮助
收藏 0 赞 0 分享

C++ explicit关键字的应用方法详细讲解

C++ explicit关键字用来修饰类的构造函数,表明该构造函数是显式的,既然有"显式"那么必然就有"隐式",那么什么是显示而什么又是隐式的呢?下面就让我们一起来看看这方面的知识吧
收藏 0 赞 0 分享

教你5分钟轻松搞定内存字节对齐

随便google一下,人家就可以跟你解释的,一大堆的道理,我们没怎么多时间,讨论为何要对齐.直入主题,怎么判断内存对齐规则,sizeof的结果怎么来的,请牢记以下3条原则
收藏 0 赞 0 分享
查看更多