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

在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写。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值