基于OpenCV的笑脸检测.docx
《基于OpenCV的笑脸检测.docx》由会员分享,可在线阅读,更多相关《基于OpenCV的笑脸检测.docx(12页珍藏版)》请在冰豆网上搜索。
![基于OpenCV的笑脸检测.docx](https://file1.bdocx.com/fileroot1/2023-1/21/fd6e02fc-ab31-450d-98cf-ee6c46af33f1/fd6e02fc-ab31-450d-98cf-ee6c46af33f11.gif)
基于OpenCV的笑脸检测
重庆交通大学信息科学与工程学院
综合性设计性实验报告
班级:
物联网150X班
姓名学号:
gllh
实验项目名称:
基于OpenCV的笑脸检测
实验项目性质:
综合性
实验所属课程:
《多媒体技术》
实验室(中心):
语音楼801信息实验室
指导教师:
娄路
实验完成时间:
2018年7月1日
目录
实验题目2
实验要求3
实验过程3
测试结果及说明4
使用SVM进行测试4
使用svm进行训练7
实验体会11
实验题目
基于OpenCV的笑脸检测
实验要求
1.分组要求:
每个学生独立完成,即1人1组。
2.程序及报告文档要求:
具有较好的可读性,如叙述准确、标注明确、截图清晰等。
实验过程
本实验使用HOG特征检测算法和SVM算法对图片进行笑脸检测,HOG特征检测算法的几个步骤:
颜色空间归一化、梯度计算、梯度方向直方图、重叠块直方图归一化然后得到HOG特征;SVM是分类算法中应用广泛、效果不错的一类。
HOG算法首先进行颜色空间归一化,由于图像的采集环境、装置等因素,采集到的人脸图像效果可能不是很好,容易出现误检或漏检的情况,所以需要对采集到的人脸进行图像预处理,主要是处理光线太暗或太强的情况,这里有两次处理:
图像灰度化、Gamma校正;之后进行图像灰度化,对于彩色图像,将RGB分量转化成灰度图像;在进行Gamma校正时,在图像照度不均匀的情况下,可以通过Gamma校正,将图像整体亮度提高或降低。
在实际中可以采用两种不同的方式进行Gamma标准化,使用梯度计算的方法,经过颜色空间归一化后的图像,求取其梯度及梯度方向。
分别在水平和垂直方向进行计算,最后HOG人脸特征及所对应的SVM分类器的参数,在opencv中已经训练好了,我们只需要得到HOG特征,然后调用SVM即可得到判别结果。
测试结果及说明
使用SVM进行测试
#include"svmTest.h"
usingnamespacecv;
intmain(intargc,constchar**argv)
{
#pragmaregionArgumentparsing
CommandLineParserparser(argc,argv,keyMap);
parser.about("FaceDetection-HOG-SVM");
if(parser.has("help"))
{
parser.printMessage();
return0;
}
StringsvmPath=parser.get("svm");
StringpositivePath=parser.get("pos");
StringnegativePath=parser.get("neg");
if(positivePath==""){
printf("ThereisnopositivePath\n");
return-1;
}
if(negativePath==""){
printf("ThereisnonegativePath\n");
return-1;
booltest=testSVM(&positivePath,&negativePath,&svmPath);
if(!
test)
return-1;
return0;
}
booltestSVM(String*positiveTestPath,String*negativTestPath,String*svmPath){
#pragmaregionInitialization
printf("Initialize\n");
//Findingallimagesinbothpathes
std:
:
vectorpositiveFileNames,negativeFileNames,allFileNames;
glob(*positiveTestPath,positiveFileNames);
glob(*negativTestPath,negativeFileNames);
//Testingifthereareimagesinthepathes
if(positiveFileNames.size()<=0){
printf("Therearenoimagesin%s\n",*positiveTestPath);
returnfalse;
}
if(negativeFileNames.size()<=0){
printf("Therearenoimagesin%s\n",*negativTestPath);
returnfalse;
}
allFileNames.insert(allFileNames.end(),positiveFileNames.begin(),positiveFileNames.end());
allFileNames.insert(allFileNames.end(),negativeFileNames.begin(),negativeFileNames.end());
//MattestData=Mat_(DESCRIPTOR_SIZE,allFileNames.size());
MattestData=Mat_(allFileNames.size(),DESCRIPTOR_SIZE);
inttestCount=0;
Ptr:
SVM>svm=ml:
:
SVM:
:
create();
svm=svm->load:
SVM>(*svmPath);
if(!
svm->isTrained()){
printf("TheSVMisn'ttrainedthroughthispath:
%s\n",*svmPath);
returnfalse;
}
HOGDescriptorhogD;
hogD.winSize=Size(WINDOW_SIZE,WINDOW_SIZE);
std:
:
vectordescriptorsValues;
std:
:
vectorlocations;
clock_tbeginTime=clock();
#pragmaendregion
#pragmaregionHOGDescriptors
//ConvertingthepositveimagesandcalculatingtheHOG
std:
:
cout<<"CalculateallImages("<<(clock()-beginTime)/(float)CLOCKS_PER_SEC<<")...";
for(std:
:
vector:
:
iteratorfileName=allFileNames.begin();fileName!
=allFileNames.end();++fileName){
MatactualImage=imread(*fileName);
//Testingifthefileisanimage
if(actualImage.empty()){
printf("Couldn'treadtheimage%s\n",*fileName);
returnfalse;
}
cvtColor(actualImage,actualImage,CV_BGR2GRAY);
resize(actualImage,actualImage,Size(WINDOW_SIZE,WINDOW_SIZE));
//CalculatingtheHOG
hogD.compute(actualImage,descriptorsValues,Size(0,0),Size(0,0),locations);
//Ineedtotransposetogeteverysampleinacolumnandnotinarow
MatdescriptorsVector=Mat_(descriptorsValues,true);
transpose(descriptorsVector,descriptorsVector);
descriptorsVector.row(0).copyTo(testData.row(testCount));
testCount++;
}
std:
:
cout<<"Finished("<<(clock()-beginTime)/(float)CLOCKS_PER_SEC<<")"<:
endl;
std:
:
cout<:
endl<:
endl;
#pragmaendregion
#pragmaregionTestingtheData
Matresults;
svm->predict(testData,results);
inttPos=0,tNeg=0;
//std:
:
cout<:
endl;
for(unsignedintc=0;cfloatresult=results.at(c,0);
if(c=1){
tPos++;
printf("asmileface\n");
}
elseif(c>=positiveFileNames.size()&&result==0)//!
=-1){
printf("notasmileface\n");
tNeg++;
}
}
returntrue;
}
使用svm进行训练
#include"svmTraining.h"
usingnamespacecv;
intmain(intargc,constchar**argv{
#pragmaregionArgumentparsing
CommandLineParserparser(argc,argv,keyMap);
parser.about("FaceDetection-HOG-SVM");
if(parser.has("help")){
parser.printMessage();
return0;
}
StringpositivePath=parser.get("pos");
StringnegativePath=parser.get("neg");
if(positivePath==""){
printf("ThereisnopositivePath\n");
return-1;
}
if(negativePath==""){
printf("ThereisnonegativePath\n");
return-1;
}
#pragmaendregion
booltrain=trainSVM(&positivePath,&negativePath);
if(!
train)
return-1;
return0;
}
booltrainSVM(String*positiveTrainPath,String*negativeTrainPath{
#pragmaregionInitialization
printf("Initialize\n");
//Findingallimagesinbothpathes
std:
:
vectorpositiveFileNames,negativeFileNames;
glob(*positiveTrainPath,positiveFileNames);
glob(*negativeTrainPath,negativeFileNames);
//Testingifthereareimagesinthepathes
if(positiveFileNames.size()<=0)
{
printf("Therearenoimagesin%s\n",*positiveTrainPath);
returnfalse;
}
if(negativeFileNames.size()<=0){
printf("Therearenoimagesin%s\n",*negativeTrainPath);
returnfalse;
}
MattrainingLabel=Mat_(1,positiveFileNames.size()+negativeFileNames.size()*RANDOM_PATCH_COUNT);
MattrainingData=Mat_(DESCRIPTOR_SIZE,positiveFileNames.size()+negativeFileNames.size()*RANDOM_PATCH_COUNT);
inttrainingCount=0;
HOGDescriptorhogD;
hogD.winSize=Size(WINDOW_SIZE,WINDOW_SIZE);
std:
:
vectordescriptorsValues;
std:
:
vectorlocations;
clock_tbeginTime=clock();
#pragmaendregion
#pragmaregionPositiveHOGDescriptors
//ConvertingthepositveimagesandcalculatingtheHOG
std:
:
cout<<"CalculatepositiveHOGDescriptors("<<(clock()-beginTime)/(float)CLOCKS_PER_SEC<<")...";
for(std:
:
vector:
:
iteratorfileName=positiveFileNames.begin();fileName!
=positiveFileNames.end();++fileName)
{
MatactualImage=imread(*fileName);
//Testingifthefileisanimage
if(actualImage.empty()){
printf("Couldn'treadtheimage%s\n",*fileName);
returnfalse;
}
cvtColor(actualImage,actualImage,CV_BGR2GRAY);
resize(actualImage,actualImage,Size(WINDOW_SIZE,WINDOW_SIZE));
//CalculatingtheHOG
hogD.compute(actualImage,descriptorsValues,Size(0,0),Size(0,0),locations);
MatdescriptorsVector=Mat_(descriptorsValues,true);
descriptorsVector.col(0).copyTo(trainingData.col(trainingCount));
trainingLabel.at(0,trainingCount)=1;
trainingCount++;
}
std:
:
cout<<"Finished("<<(clock()-beginTime)/(float)CLOCKS_PER_SEC<<")"<:
endl;
#pragmaendregion
#pragmaregionNegativeHOGDescriptors
//CalculatingtheHOGofthenegativimages
std:
:
cout<<"CalculatenegativeHOGDescriptors("<<(clock()-beginTime)/(float)CLOCKS_PER_SEC<<")...";
for(std:
:
vector:
:
iteratorfileName=negativeFileNames.begin();fileName!
=negativeFileNames.end();++fileName){
MatactualImage=imread(*fileName);
//Testingifthefileisanimage
if(actualImage.empty()){
printf("Couldn'treadtheimage%s\n",*fileName);
returnfalse;
}
cvtColor(actualImage,actualImage,CV_BGR2GRAY);
resize(actualImage,actualImage,Size(WINDOW_SIZE,WINDOW_SIZE))
//CalculatingtheHOG
hogD.compute(actualImage,descriptorsValues,Size(0,0),Size(0,0),locations);
MatdescriptorsVector=Mat_(descriptorsValues,true);
descriptorsVector.col(0).copyTo(trainingData.col(trainingCount));
trainingLabel.at(0,trainingCount)=0;
trainingCount++;
}
std:
:
cout<<"Finished("<<(clock()-beginTime)/(float)CLOCKS_PER_SEC<<")"<:
endl;
#pragmaendregion
#pragmaregionSVMTraining
//SetupSVM'sparameters
Ptr:
SVM>svm=ml:
:
SVM:
:
create();
svm->setType(ml:
:
SVM:
:
C_SVC);
svm->setKernel(ml:
:
SVM:
:
LINEAR);
svm->setTermCriteria(cvTermCriteria(CV_TERMCRIT_ITER,SVM_ITERATIONS,1e-6));
//CreatetheTrainingdata
Ptr:
TrainData>tData=ml:
:
TrainData:
:
create(trainingData,ml:
:
SampleTypes:
:
COL_SAMPLE,trainingLabel);
std:
:
cout<<"StartSVMtraining("<<(clock()-beginTime)/(float)CLOCKS_PER_SEC<<")...";
svm->train(tData);
std:
:
cout<<"Finished("<<(clock()-beginTime)/(float)CLOCKS_PER_SEC<<")"<:
endl;
svm->save(SVM_OUTPUT_NAME);
#pragmaendregion
returntrue;
}
将图片集分为训练集和测试集,之后分为笑脸集和非笑脸集:
将每个集合中图片先识别其中人脸:
之后进行梯度变换并使用SVM进行分类
实验体会
通过这次设计性综合性实验,通过利用基于OpenCV的HOG特征提取算法提取人脸特征,其中进行颜色空间归一化,并对图像进行灰度化,之后进行Gamma校正,经过校正后对垂直和水平方向进行梯度计算,并将图片划分成若干个单元形成梯度方向直方图,并使用SVM分类算法对图片进行笑脸非笑脸进行分类,先使用SVM算法得到超平面,求出差值进行对比。
此SVM方法和之前机器学习课程中学到的分类算法类似,通过本次实验,学习到了基于OpenCV的HOG特征提取方法和基本步骤,掌握了SVM分类方法中线性和非线性分类之间的处理,此次实验不但将多媒体技术这门课程中所学的基于OpenCV的HOG特征提取算法相结合,并且和机器学习之中的SVM分类算法相结合,融会贯通,相辅相成,通过这次的实验,触类旁通,可以将此算法应用到多个应用场景当中,本次实验对今后的学习和工作都有很大帮助。