【注意】本博文的档次适合OpenCV初学者,和要做本科生毕业设计这类档次。
上一节是人脸采集,链接如下:
http://blog.csdn.net/qq78442761/article/details/71158472
源码的下载地址和原理理论部分请走下面连接
http://blog.csdn.net/qq78442761/article/details/71157980
本节讲解Opencv中的人脸处理,
功能如下:
当我们点击了功能里面的照片处理后,如下所示:
并且在Data目录下,可以看见生成了一个对应的文件夹,这个文件夹和peopel.txt里面的标识对应,如下图所示:
下面来看代码
void AddPeople::disposePic()
{
file.CreateFile(QString::number( MaxNumAboutPeople,10));
QString sourceFilePath="addData\\";
QString targetFilePath="Data\\"+QString::number(MaxNumAboutPeople,10);
targetFilePath.append("\\");
QString sourceFile;
QString targetFile;
for(int i=0;i<10;i++)
{
sourceFile.append(sourceFilePath+QString::number(i+1,10));
sourceFile.append(".jpg");
targetFile.append(targetFilePath);
targetFile.append(QString::number(i,10));
targetFile.append(".jpg");
this->detectAndDisplay(sourceFile,targetFile);
sourceFile.clear();
targetFile.clear();
}
}
这是创建文件夹的代码,是不是很简单呢?其实就是调用了file.h,我们现在进入file.h和file.cpp来看看
如果创建文件夹:
void MyFILE::CreateFile(QString fileName)
{
PicFile=new QDir;
QString path="Data\\"+fileName;
if(PicFile->exists(path))
{
QMessageBox about;
about.setText(tr("文件夹创建失败"));
about.exec();
}
else
{
if(PicFile->mkdir(path))
{
QMessageBox about;
about.setText(tr("文件夹创建成功"));
about.exec();
}
}
}
而关于存储图像和处理在detectAndDisplay(sourceFile,targetFile);这个函数中。
现在来看此函数:
void AddPeople::detectAndDisplay(QString source, QString target)
{
std::string face_cascade_name = "haarcascade_frontalface_alt.xml";
cv::CascadeClassifier face_cascade; //定义人脸分类器
cv::Mat frame = cv::imread(source.toStdString());
if(!frame.data)
{
qDebug()<<source;
QMessageBox::warning(this,tr("提示"),tr("frame读取失败"),QMessageBox::Ok);
return;
}
if (!face_cascade.load(face_cascade_name))
{
QMessageBox::warning(this,tr("错误"),tr("haarcascade_frontalface_alt.xml加载失败"),QMessageBox::Ok);
return;
}
std::vector<cv::Rect> faces;
cv::Mat img_gray;
cv::cvtColor(frame, img_gray, cv::COLOR_BGR2GRAY);
cv::equalizeHist(img_gray, img_gray);
face_cascade.detectMultiScale(img_gray, faces, 1.1, 3, CV_HAAR_DO_ROUGH_SEARCH, cv::Size(50, 50));
for (int j = 0; j < (int)faces.size(); j++)
{
cv::Mat faceROI = frame(faces[j]);
cv::Mat MyFace;
cv::Mat gray_MyFace;
if (faceROI.cols > 100)
{
cv::resize(faceROI, MyFace, cv::Size(92, 112));
cv::cvtColor(MyFace, gray_MyFace, CV_BGR2GRAY);
imwrite(target.toStdString(), gray_MyFace);
}
}
}
这里的代码说白了就是调用haarcascade找人脸,分割人脸,然后进行灰度处理,和直方图均衡化,然后进行imwrite保存文件。
进行灰度处理,和直方图均衡化是为了训练模型时减少计算,减少冗余信息对识别的影响,提供识别准确度。
10张图片处理完毕了,下面我们生成csv文件。
csv也就是逗号分割的文件,也就是说,我们有10张图,如果10个人就100张图,为了操作方便,为何不用一个文件把这些图的路径和人脸的标号放在一起,让Opencv直接读取,这样才方便。
当点击生成csv后如下图所示:
这个at.txt文件是预先创建好的。
其实功能就是把相对路径换成绝对路径,方便Opencv进行读取。这里有个坑要注意,Opencv中读取csv文件只能是ASCII编码,如果不是ASCII将读取不了,如下图所示:
现在来看代码,如何完成这样的工作:
void AddPeople::AddCSV()
{
file.MakecsvFile();
}
在Addpeople中AddCSV调用了file.MakecsvFile,现在进去看他具体的代码:
void MyFILE::MakecsvFile()
{
QDir csvFile("./Data/at.txt");
QString csvPath=csvFile.absolutePath();
QString csvFilePath=csvPath;
csvPath.chop(6);
QString path=csvPath+QString::number(MaxNumAboutPeople,10)+"/";
for(int i=0;i<10;i++)
{
QString filepath=path;
filepath.append(QString::number(i,10));
filepath.append(".jpg;");
filepath.append(QString::number(MaxNumAboutPeople,10));
//this->AddPeople(csvFilePath,filepath);
QFile file(csvFilePath);
if(!file.open(QIODevice::WriteOnly|QIODevice::Append))
{
QMessageBox about;
about.setText(tr("添加人员时文件打开失败"));
about.exec();
return;
}
QTextStream in(&file);
//in.setCodec("UTF-8");
in<<filepath<<"\r\n";
file.close();
}
}
是不是和上一节创建文件一样简单呢!
下一节将说明模型训练!
源码和理论部分在本博文开头有提供。