场景需求
在用C++编程时,有保存数据的需求就有加载数据的需求,加载EXCEL数据的方式各式各样,本文主要针对上篇文章讲的“保存图像数据至EXCEL”,提供了一种对应的加载EXCEL图像数据的函数。大家可以根据自身需求进行修改。
功能函数代码
cv::Mat ReadPicFromExcel(string name) { // result是所要提取的图像 cv::Mat result,pic; // 所要提取文件的名字 ifstream infile(name); string str; int col = 0; // 一行行读取 while (getline(infile, str)) { string temp; stringstream input(str); col = 0; // 单个数据提取 while (input >> temp) { // 如果是字符“nan”,则输入nan("");否则输入数据 if (temp == "nan") { pic.push_back(float(nan(""))); } else { pic.push_back(float(atof(temp.c_str()))); } col++; } } // reshape变换成正常row*col的矩阵 int row = pic.rows / col; result = pic.reshape(0, row); // 关闭 infile.close(); // 返回图像矩阵 return result; }
C++测试代码
#include<iostream> #include<fstream> #include<opencv2/opencv.hpp> using namespace std; void WritePicToExcel(string name, cv::Mat pic); cv::Mat ReadPicFromExcel(string name); int main() { cv::Mat pic = cv::Mat::zeros(1000, 1000, CV_32FC1); for (int i = 0; i < pic.rows; i++) { for (int j = 0; j < pic.cols; j++) { pic.at<float>(i, j) = rand() % 255; } } pic.at<float>(1, 2) = nan(""); WritePicToExcel("test1.xls", pic); cv::Mat result = ReadPicFromExcel("test1.xls"); return 0; } void WritePicToExcel(string name, cv::Mat pic) { CV_Assert(pic.type() == CV_32FC1); ofstream outfile(name); int row = pic.rows; int col = pic.cols; for (int i = 0; i < row; i++) { float *p = pic.ptr<float>(i); for (int j = 0; j < col; j++) { if (p[j] == p[j]) { outfile << p[j] << (j == (col - 1) ? '\n' : '\t'); } else { outfile << "nan" << (j == (col - 1) ? '\n' : '\t'); } } } outfile.close(); } cv::Mat ReadPicFromExcel(string name) { // result是所要提取的图像 cv::Mat result,pic; // 所要提取文件的名字 ifstream infile(name); string str; int col = 0; // 一行行读取 while (getline(infile, str)) { string temp; stringstream input(str); col = 0; // 单个数据提取 while (input >> temp) { // 如果是字符“nan”,则输入nan("");否则输入数据 if (temp == "nan") { pic.push_back(float(nan(""))); } else { pic.push_back(float(atof(temp.c_str()))); } col++; } } // reshape变换成正常row*col的矩阵 int row = pic.rows / col; result = pic.reshape(0, row); // 关闭 infile.close(); // 返回图像矩阵 return result; }
测试效果
图1 随机生成的图像矩阵
图2 保存效果图
图3 读取效果
如上图所示,为了方便,我随机生成了一个1000*1000的图像矩阵,并定义了第二行第三列的点为nan值,保存效果如图2所示,成功;再用加载数据的函数,得到的result同之前的pic一致。
如果函数有什么可以改进完善的地方,非常欢迎大家指出,一同进步何乐而不为呢~
如果文章帮助到你了,可以点个赞让我知道,我会很快乐~加油!