您的位置:首页 > 编程语言 > C语言/C++

tensorflow数据集处理:CSV中绝对路径转相对路径(C++写)

2018-09-19 11:34 681 查看

在tensorflow数据集制作过程中,标记后的数据通常和样本在同一路径下。
在标记数据中,有一列数据为图片路径,一般保存为相对路径形式:即相对于图片所在目录的路径;然而,通过Matlab直接保存的为绝对路径,因此需要转换。

为什么要保存成相对路径呢?

  • 比如共享的数据集,被转移路径后,绝对路径会发生变化,需要重新生成CSV文件,很麻烦;
  • 而且保存在同一路径下,相对路径在读取图片时候,也比较节省时间。

我们分析一下绝对路径的格式:
诸如:
D:/pictures/labels/group_1/img_23.jpg

在进入图像路径后,直接遍历这个路径下的所有图片。
所以只要保存以下格式:
img_23.jpg

所以问题转化为:截取绝对路径中最后一个反斜杠之后的数据

处理思路

在被一个大神点播之后,提出以下思路:

  1. 路径对应的字符串倒序排布;
  2. 遍历倒序后字符串,并将其保存在另一个字符串,第一次遇到反斜杠就终止;
  3. 将保存的字符串倒序,即可得到不含路径的图片名称。

CSV中绝对路径批量处理

CSV格式跟excel差不多,只不过一个是表格保存,一个是通过逗号间隔每个字符串。笔者路径在第一列,这个可以根据具体情况选择位置。
批量处理其实需要读写文件,流程如下:

  1. 读文件:以读的方式打开CSV文件,按行读取字符,并将其保存,可用vector<vector>格式保存;

  2. 改文件:寻找到filename所在的列,可以直接阅读文件,或者通过vector的find函数定位;

    注意:CSV文件第一行为文件头,需要特殊处理,在修改时不进行操作。

  3. 写文件:将修改后的数据按序写入源文件。

    注意:以写的方式打开文件时,源文件数据清空;不过没关系,我们已经将数据保存在内存。

经过这样的处理,绝对路径相对路径灵活运用,若是遇到行列参数编写序号不合tensorflow格式的,也可以通过这种方式。
实际效果如下:

实际操作时候,我把改数据和写文件放在一个流程。
板块复制粘贴功能暂时失效,代码如下:

//字符串倒序操作
void reverseString(string & str)
{
int i = 0, j = str.length() - 1;
while (i < j)
{
std::swap(str[i++], str[j--]);
}
}

//绝对路径改为相对路径
void Path_Absolute_Relative(string &absolutepath,string &relativepath)
{
char line_1[] ="/" ;
char line_2[] = "//";
char line_3[] = "\\";
char *outpath = new char[10];

reverseString(absolutepath);//绝对路径倒序

for (int i = 0; i < absolutepath.length();i++ )
{
if ((absolutepath[i] != line_1[0]) && (absolutepath[i] != line_2[0]) && (absolutepath[i] != line_3[0]))
{
outpath[i] = absolutepath[i];//将倒序后绝对路径反斜杠前的字符保存到相对路径
}
else
{
outpath[i] = '\0';
break;
}
}
relativepath = outpath;
reverseString(relativepath);//相对路径倒序

}

//运行主函数
int main()

{
ifstream fin("D:/boat.csv"); //打开文件流操作,改成自己的CSV文件路径

string line;

vector<vector<string>> datafromfile;

// 读文件,将文件数据保存到本地
while (getline(fin, line))   //整行读取,换行符“\n”区分,遇到文件尾标志eof终止读取
{
istringstream sin(line); //将整行字符串line读入到字符串流istringstream中

vector<string> fields; //声明一个字符串向量

string field;

while (getline(sin, field, ',')) //将字符串流sin中的字符读入到field字符串中,以逗号为分隔符
{
fields.push_back(field); //将刚刚读取的字符串添加到向量fields中
}
datafromfile.push_back(fields);
}
//关闭文件
fin.close();
//写文件形式打开,此时文件被清空,数据保存在本地
ofstream file("D:/boat.csv");

for (int i = 0; i < datafromfile.size(); i++)
{
if (i != 0)
{
string relativepath;

//改写文件名,将绝对路径只保存文件名称
//如果改成相对路径,只需要写字符串和参照路径对比,保存差异部分,即为相对路径
//第一行为文件头,不做修改
//此处操作可以CSV行列调序一类

Path_Absolute_Relative(datafromfile[i][0], relativepath);

datafromfile[i][0] = relativepath;

}
//将数据写入文件
for (int j = 0; j < datafromfile[i].size()-1; j++)
{
file << datafromfile[i][j] << ",";
}
int end = datafromfile[i].size() -1;//最后一位特殊处理
file << datafromfile[i][end] << endl;
}

file.close();
}

代码大概这样,C++写的,还没尝试Matlab写。

阅读更多
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: