C++ 读取CSV文件中的数据到Mat

目标

最近正在做热图像的实验数据处理,热像仪上位机导出热图像视频数据是,每一帧为一个csv文件,每行像素值由逗号分隔,行与行之间是换行符,数据格式是纯文本,科学计数法。需要将全部数据存至一个mat中,以便后续使用opencv库处理。
excel打开的效果
记事本打开的效果

思路

  1. 将读取CSV文件的函数和当前正在读取的文件操作符等放在一个类中,构造类似句柄的一个类,代表一个帧的文件。
  2. 类中包含如打开、关闭、检查列数、(没有写检查行数的函数)、科学计数法转浮点数等基本操作。
  3. Mat类引用传参。
  4. 以固定格式打开CSV文件,比如打开一段视频的第一帧就传入参数1。
    代码

程序

读取CSV的类

//read_csv.h
#ifndef READ_CSV_H
#define READ_CSV_H
#include <iostream>
#include <fstream>
#include <vector>
#include <string>
#include <sstream>//istringstream 必须包含这个头文件
#include <opencv2\opencv.hpp>
using namespace std;
using namespace cv;
class CSV {
public:
    CSV(int b, int r);//b为列数
    ~CSV();
    void check_columns(void);//判断该数据有多少列
    void read_csv(int n,Mat& dest);//读取哪一帧数据
    void file_close(void);//--关闭所有打开的文件
    void open_csv(int idx);//打开第idx帧的文件
    /*
    void creat_new_csv(void);//--创建一个新的csv文件
    void write_csv(void);//--将需要的数据写入新csv文件中
    */
public:
    int columns;
private:
    string  filename_base = "H:/data/2__";//--打开的文件名
    string oneline;//--保存一行数据
    ifstream infile;//--输入文件流
    ofstream outfile;//--输出文件流
    int blank_rows = 0, rows, current_frame = 0;//无效行数,列数,当前帧
};
double sci2db(string& strSci);
#endif // !READ_CSV_H

filename_base 是基础文件名,在上位机导出时设置,后面跟着上位机自动补全的第几帧。
blank_rows是无效的行数,上位机会生成几行记录相关信息。

#include "read_csv.h"
/*
每一帧是一个文件
*/

CSV::CSV(int b,int r=240)//构造函数
{ 
    this->blank_rows = b; //设定空白行数
    check_columns();//检查列数
    this->rows = r;
}
CSV::~CSV() //析构函数
{   
    if(this->infile.is_open())
        this->infile.close();//有文件打开则关闭文件
}
void CSV::check_columns(void) 
{
    open_csv(1);//打开第一帧,编号从一开始
    string tmp;
    for (int i = 0; i < blank_rows; i++)
    {
        getline(this->infile, tmp);//--读取一行
    }
    getline(this->infile, tmp);//--读取一行
    this->columns = 1;
    for (int i = 0; i < tmp.size(); i++) {
        if (tmp[i] == ',')this->columns++;
    }
    cout <<"There exists "<<this->columns <<" columns in the file "<< endl;
    file_close();//关闭文件
}

void CSV::read_csv(int n,Mat& dest)
{
    dest.create(this->rows, this->columns, CV_64FC1);
    open_csv(n);
    for (int i = 0; i < this->rows; i++) {
        getline(this->infile, this->oneline);//--读取一行
        istringstream tempstream(this->oneline);//将整行字符串line读入到字符串流istringstream中
        string field;
        int m = 0;
        for (int j = 0; j < this->columns; j++) {
            getline(tempstream, field, ',');
            /* 注意 Mat::at 函数是个模板函数, 需要指明参数类型, 因为这张图是具有红蓝绿三通道的图,
              所以它的参数类型可以传递一个 Vec3b, 这是一个存放 3 个 uchar 数据的 Vec(向量). 这里
              提供了索引重载, [2]表示的是返回第三个通道, 在这里是 Red 通道, 第一个通道(Blue)用[0]返回 */
            dest.at<double>(i, j) = sci2db(field);
        }
    }

    file_close();//关闭文件
}
void CSV::open_csv(int idx)
{
    string filename = filename_base + to_string(idx) + ".csv";//--写入文件名
    this->infile.open(filename); //--打开文件
}
void CSV::file_close(void)
{
    this->infile.close();
}
double sci2db(string& strSci)
{
    int    iPower = 0;  //幂
    double dMntsa = 0;  //尾数
    double dCoefficient = 1;  //系数
    std::string strPower, strMntsa;
    if (std::string::npos == strSci.find("E"))
    {
        return atof(strSci.c_str());
    }
    strMntsa = strSci.substr(0, strSci.find("E"));
    strPower = strSci.substr(strSci.find("E") + 1);
    dMntsa = atof(strMntsa.c_str());
    iPower = atoi(strPower.c_str());
    while (iPower != 0)
    {
        if (iPower > 0)
        {
            dCoefficient *= 10;
            iPower--;
        }
        else
        {
            dCoefficient *= 0.1;
            iPower++;
        }
    }
    return dMntsa * dCoefficient;
}
/*temp
void CSV::write_csv(void)
{
    this->outfile << this->fields[8] << "," << this->fields[10] << endl;
}
void CSV::creat_new_csv(void)
{
    this->outfile.open("out.csv", ios::out | ios::trunc);
}

void CSV::open_csv(void)
{
    if(filename.size()!=0)
        this->infile.open(this->filename); //--打开文件
}
*/

主函数示例

简单写一个读取每一帧吧

#include <opencv2\opencv.hpp>
#include "read_csv.h"
using namespace cv;
using namespace std;
int start_frame = 1000, end_frame = 6000;//起始帧和终点帧
int main()
{
	CSV csv_1(0,240);
	Mat read_tmp;
	for (int i = start_frame; i < end_frame;i++) {
		csv_1.read_csv(i, read_tmp);//读取第i帧图像
        //···
	}
	//···
	//system("PAUSE ");
	return 0;
}

读取CSV文件C++代码可以使用ifstream和stringstream来实现。以下是一个读取CSV文件并将其存储为字符串数组的示例代码: ```cpp #include <iostream> #include <string> #include <vector> #include <fstream> #include <sstream> using namespace std; int main() { ifstream inFile("D:\\aa\\bb.csv"); string lineStr; vector<vector<string>> strArray; while (getline(inFile, lineStr)) { cout << lineStr << endl; stringstream ss(lineStr); string str; vector<string> lineArray; while (getline(ss, str, ',')){ lineArray.push_back(str); } strArray.push_back(lineArray); } } ``` 这段代码首先使用ifstream打开了一个名为"D:\\aa\\bb.csv"的CSV文件,并使用getline逐行读取文件内容。然后,使用stringstream将每行内容按逗号分割为多个字符串,并将这些字符串推入到vector,最后将每一行的vector推入到一个二维vector。 如果您需要将数据转换为其他类型,比如将字符串转换为浮点数,可以参考下面的示例代码: ```cpp #include <iostream> #include <string> #include <vector> #include <fstream> #include <sstream> using namespace std; int main() { ifstream inFile("D:\\LaneChangeDecision\\lc_data\\train_data_v0719.csv"); string lineStr; vector<vector<float>> strArray; while (getline(inFile, lineStr)) { stringstream ss(lineStr); string str; vector<float> lineArray; while (getline(ss, str, ',')){ float str_float; istringstream istr(str); istr >> str_float; lineArray.push_back(str_float); } strArray.push_back(lineArray); } } ``` 在这段代码,我们首先定义了一个vector<vector<float>>来存储浮点数数据。然后,使用istringstream将每个字符串转换为浮点数,并将其推入到lineArray,最后将每一行的lineArray推入到strArray。 请注意,以上代码只是演示了如何读取和转换CSV文件数据,您需要根据自己的具体需求进行相应的修改。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *3* [C++ 读取csv文件(复制即可用)](https://blog.csdn.net/qq_39332551/article/details/125931529)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT0_1"}}] [.reference_item style="max-width: 50%"] - *2* [C++读写CSV文件](https://blog.csdn.net/weixin_43531632/article/details/122281033)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT0_1"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

清欢_小铭

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值