要进行训练,那样本的读取和分类就是需要搞定的了。这篇文字主要记录c++、python的文件操作,包含文件夹的遍历、文件的读取判断等。不定期更新。
5.9:c++如何进行文件夹的遍历
看了一些文章,说包含 io.h 就能进行相关操作了,可是我ubuntu怎么都找不到 io.h。
于是想了一个办法,我要进行人脸识别,每次录入样本后会单独存在一个文件夹里,然后训练之前要生成样本的描述文件。
我是这样解决的,录入样本,记录样本文件夹名字在一个txt文件中,然后新一次录入和前面的对比,不一样则标签定位在文件末尾,标签加一。生成描述文件时,先读取txt文件中的名字,存在一个vector中,然后再进行每个文件夹的读取。
用到的c++文件操作有:
进行文件每行信息的提取,对比,不一样的样本名存在末尾
- 以读取打开文件
- 逐行读取,并每行进行分割,分出标签和名字
- 替换或者定位到末尾。
#include <iostream>
#include <fstream>
#include <sstream>
#include <dirent.h>
bool save_samplename(string name){
char separator = ' ';
string line, old_name, classlabel;
fstream f;
f.open(names_file,ifstream::in);
if(!f){
ofstream fc(names_file,ofstream::out);
fc.close();
f.open(names_file,ifstream::in);
}
int last_label = -1;
while (!f.eof()) {
getline(f, line);
//cout << line << endl;
stringstream lines(line);
getline(lines, old_name, separator);//获取样本名字
getline(lines, classlabel); //获取标签
if(name == old_name)
return 0;
if(!classlabel.empty())
last_label = atoi(classlabel.c_str());
else if(!old_name.empty())
break;
}
f.close();
ofstream fo; //写打开
fo.open(names_file,ofstream::app); //定位到文章末尾
last_label ++;
fo<<name<<separator<<last_label<<endl;
fo.close();
return 1;
}
- 介绍一下该txt文件的读取与分割,其格式为
youj 0
xiaom 1 - 先以读取打开文件
- 然后进行逐行读取
- 再利用 ccstream 进行行分割(空格)读取
getline(f, line);
//cout << line <<endl;
if(line.empty())
break;
//lines.push_back(line.c_str());
stringstream lines(line);
getline(lines, old_name, separator);//获取样本名字
getline(lines, classlabel); //获取标签
name.push_back(old_name.c_str());
label.push_back(atoi(classlabel.c_str()));
进行母文件夹中找知道名字的子文件夹,并遍历该子文件夹 包含 dirent.h
并生成csv描述文件
- 读取txt文件中的名字(即子文件夹)和标签
- 打开子文件夹,利用
dir = opendir(m[i].c_str());
- 遍历,
while((ptr = readdir(dir)) != NULL) //循环读取目录下数据
- 输出遍历的文件名,
filename = ptr->d_name; //输出文件名
void get_namescsv()
{
DIR *dir;
struct dirent * ptr;
string rootdirPath = mum_path;
string filename;
vector<string> m;
vector<int> l;
read_names(m,l);
ofstream csv;
csv.open(listpath,ofstream::out);
for(int i = 0;i < m.size();i++){
m[i] = mum_path+"/"+ m[i];
cout << m[i].c_str() << " "<<l[i]<<endl;
dir = opendir(m[i].c_str());
while((ptr = readdir(dir)) != NULL)//(为什么这个遍历机制不会在扫描完成之前重复扫描)!!!很好用
{
filename = ptr->d_name; //输出文件名
if(filename[0] == '.') //过滤隐藏文件
continue;
csv << m[i]+"/"+filename +" "<<l[i]<<endl;
}
}
csv.close();
}
python进行文件夹的遍历并生成描述文件##
python进行文件操作就非常简单容易了,下面介绍两种方式
方式一:
- os.listdir列出所有子文件夹,注意列出的是文件夹名,后面需要加 ‘/’
- os.listdir(path)列出子文件夹中的文件
- 可以在第二步前加上判断是否是文件夹,if os.path.isdir(file_img):
import sys
import os
DataPath = "face/" #/home/jiang/Repositories/人脸识别/cv-face_predict/face
datalistname = "train.csv"
dirList = os.listdir(DataPath) #列出文件夹的所有文件
if os.path.exists(DataPath+datalistname):
print "err please delete"
#os.remove(os.path.join(DataPath, datalistname))
os.remove("face/train.csv")
for name in dirList:
path = DataPath + str(name) + '/'
print path
cpath = str(path)[16:str(path).rfind('/')+1]
f = open(DataPath+datalistname,'a+')
fileList = os.listdir(path)
for fileName in fileList:
print fileName
f.write(cpath + fileName + ';' + '\n')
方式二
- 直接粗暴方式for root, dirs, files in os.walk(mum_path):
- 分别返回 母文件夹名、所有文件夹名、所有文件名
- 文件名拼接 filepath = os.path.join(root,filename)
for root, dirs, files in os.walk("./train"): # os.path.basename("/etc/sysconfig/selinux") 'selinux'
#print dirs
for filename in files:
root_int = root.split('/')[2] #文件夹的名字,即标签 0-9
filepath = os.path.join(root,filename)
#print filepath