如果觉得这篇文章对您有所启发,欢迎关注我的公众号,我会尽可能积极和大家交流,谢谢。
在C语言编程中经常遇到一个问题:如何批量读取一个目录下某一类型的所有文件,例如图像文件。最近在研究图像模式分类问题,经常需要对某一种分类器进行训练,在训练过程中需要遍历某一文件夹下的几百甚至几千张图片样本,如何用程序完成这个遍历工作,实在是一个问题,在此对其中的一种解决办法——CSV文件读取方法,进行详细介绍。
所谓CSV文件,就是一种纯文本文件,即记事本文件,这种文件可以通过DOS命令生成。通过CSV文件批量读取数据的思路如下:首先通过DOS命令生成一个txt文件,这个文件内容很多行,其中每行均是一个目标文件在计算机中的全路径名。然后在程序中分别读取每行中相应的内容,定位文件,逐个完成读取。
举个例子,我有400张图片,分别存放在E盘下名为ORL文件夹下的40个子文件夹中,每个文件夹有十张图片,扩展名统一为*.bmp格式,如何完成对这400张图片的读取?下面结合实例代码来具体谈一下这个问题。
首先是CSV文件的创建,这需要通过DOS命令进行操作。打开命令提示符窗口后,默认为系统路径(不同电脑可能不一样),输入命令“E:”,回车,进入E盘,然后再输入“cd/ORL”,回车,进入ORL文件夹中,然后输入命令“dir/b/s *.bmp > at.txt”,回车,之后就会发现在ORL文件夹中生成了一个名为“at”的txt文件,打开之后发现里面存储了该目录下不同子目录中所有文件的路径,至此CSV文件创建成功。
CSV文件创建好之后就可以在程序中读取相应的文件,在这里写了一个简单的读取函数与大家分享,代码如下:
void read_csv(const string& filename, vector<Mat>& images)
{
ifstream file(filename, ifstream::in);//创建一个输入流对象
if (!file)//如果输入流创建失败,则报错,程序终止
{
string error_message ="No valid input file was given.";
CV_Error(CV_StsBadArg, error_message);
}
string path;//string变量,用以存储读出的路径
while (getline(file,path))//从文件中读出一行的内容,保存在变量path中
{
if (!path.empty())
{
images.push_back(imread(path,0));//将对应文件压入图像容器
}
}
}
这里需要说的一点就是getline()函数,如果未加限制条件,则默认从文本文件的第一行开始读,遇到“/n”停止,下次读取时在此位置接着向下读。不过这个函数是可以人为加条件使其停止读入字符的,可以在数量上进行限制,如读入固定个字符后自动停止;或者在字符上进行限制,即读到某个特定的字符则停止。
最后只需在程序中调用read_csv()函数即可,代码如下:
int _tmain(int argc, _TCHAR* argv[])
{
vector<Mat> image;
string file_csv = "E:\\ORL\\at.txt";
read_csv(file_scv,image);
return 0;
}
通过调用read_csv(file_scv,image)函数,能够把所有图像文件读取到创建的图像容器image中。
最后说明一点,就是这种方法还能够批量读取带标签的图像样本,只需在原函数的基础上做一些小小的改动就行了,这部分内容在我的一篇有关opencv人脸识别的博文中提过
如果觉得这篇文章对您有所启发,欢迎关注我的公众号,我会尽可能积极和大家交流,谢谢。