最近参加一个比赛,提供了一个CSV文件,内容如下
参考博客 https://blog.csdn.net/u013232740/article/details/50828062
由于这里的数据都比较规整,没有无效字符等,于是照着博客改写了一下,达到了我读数据的目的
这里把读到的数据拿出来用于图片标记,其实就是把图片里面所需要的ROI框出来
#include<iostream>
#include"opencv2/opencv.hpp"
#include<fstream> // for ifstream
#include<vector> // for vector
using namespace std;
using namespace cv;
struct Coordinate
{
int x;
int y;
int w;
int h;
};
int main()
{
// ont statements
ifstream _csvInput("C:\\Users\\Administrator\\Desktop\\卡口\\卡口图片打标\\train_b.csv");
// or two statements by using .open("path")
string _Oneline;
vector<string> _lineOfstr; // 声明一个字符串向量用于存放图片ID和打标数据
while (getline(_csvInput, _Oneline)) // 整行读取,换行符“\n”区分,遇到文件尾标志eof终止读取
{
istringstream _Readstr(_Oneline); // 将整行字符串_Oneline读入到字符串流istringstream中
string _partOfstr;
if (_Oneline == "name,coordinate") // 第一行不读取
continue;
while (getline(_Readstr, _partOfstr, ',')) // 将字符串流_Readstr中的字符读入到_partOfstr字符串中,以逗号为分隔符
{
_lineOfstr.push_back(_partOfstr); // 将刚刚读取的字符串添加到向量_lineOfstr中,
}
}
// 于是_lineOfstr[i]则是图片路径,_lineOfstr[i+1]就是12_14_356_66;13_15_165_226
for (int i = 0; i < _lineOfstr.size(); i+=2)
{
// split
vector<string> _str_coordinate;
stringstream ss1(_lineOfstr[i + 1]);
while (getline(ss1, _lineOfstr[i + 1], ';'))
{
_str_coordinate.push_back(_lineOfstr[i + 1]);
}
// 上面这里将以分号为间隔提取了每一个坐标参数
vector<string> parameter;
for (int j = 0; j < _str_coordinate.size(); ++j)
{
stringstream ss2(_str_coordinate[j]);
int flag = 1;
while (getline(ss2, _str_coordinate[j],'_'))
{
parameter.push_back(_str_coordinate[j]);
}
}
// 得到的parameter是以4个为一个周期的参数x,y,w,h
vector<Coordinate> coordinate;
for (int k = 0; k < parameter.size(); k += 4)
{
int _x = stoi(parameter[k]);
int _y = stoi(parameter[k + 1]);
int _w = stoi(parameter[k + 2]);
int _h = stoi(parameter[k + 3]);
Coordinate pre_coordinate = { _x, _y, _w, _h }; //放入结构体中
coordinate.push_back(pre_coordinate);
}
// 得到的coordinate向量存储了每张图片对应的全部参数
// rectangle cars
stringstream _picPath;
_picPath << "C:\\Users\\Administrator\\Desktop\\卡口\\卡口图片打标\\train_b\\" << _lineOfstr[i];
Mat _image = imread(_picPath.str());
// 将参数全都绘制到图像上
for (int c = 0; c < coordinate.size(); ++c)
{
rectangle(_image, Rect(coordinate[c].x, coordinate[c].y, coordinate[c].w, coordinate[c].h), Scalar(0, 255, 0));
}
// 保存绘制图像即可
stringstream _picSavePath;
_picSavePath << "C:\\Users\\Administrator\\Desktop\\卡口\\savetest\\" << _lineOfstr[i];
imwrite(_picSavePath.str(), _image);
}
return 0;
}
反过来,如果需要写入CSV文件,CSV文件其实就是文本文件,每行字段用逗号分隔
#include <iostream>
#include <string>
#include <vector>
#include <fstream>
#include <sstream>
using namespace std;
int main()
{
// 写文件
ofstream outFile;
outFile.open("data.csv", ios::out); // 打开模式可省略
outFile << "name" << ',' << "age" << ',' << "hobby" << endl;
outFile << "Mike" << ',' << 18 << ',' << "paiting" << endl;
outFile << "Tom" << ',' << 25 << ',' << "football" << endl;
outFile << "Jack" << ',' << 21 << ',' << "music" << endl;
outFile.close();
// 读文件
ifstream inFile("data.csv", ios::in);
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);
}
getchar();
return 0;
}