基于Gabor+PCA+SVM的性别识别(1): http://www.cnblogs.com/xiaoming123abc/p/5078411.html
基于Gabor+PCA+SVM的性别识别(2): http://www.cnblogs.com/xiaoming123abc/p/5078792.html
基于前两博文,已经训练出一个性别分类器。那就应该运用这个分类器进行性别分类。
这个测试过程与训练过程一样。只不过,训练时,是大批量的处理样本数据数据。测试过程,针对需要识别的图像进行处理。
结果分析:
训练过程man样本 409,woman样本287。其实,对于机器学习来说,这些样本还是很少的。在进行测试时,6个man图像可以正确识别。woman图像识别过程出现了错误识别。因为样本图片都是老外,而且人数有限。对其他图片效果应该不是很好。
本人分析的主要原因有两点:1)在训练过程,Gabor小波、PCA降维过程的参数选取没有进行严格的测试;
2)训练样本太少,而且样本中就那几个人的脸。可以增加训练样本的数量。
最后还得提一点,由于训练过程运算量大。训练600多个样本,运行了应该有半个小时。
main.cpp (Gabor类文件同(2))
#include
#include
#include
#include "GaborFR.h"
using namespace cv;
using namespace std;
Mat detectAndDisplay( Mat);
//加载Opencv自带人脸识别级联分类器文件
string face_cascade_name ="D:\\Program Files\\opencv\\sources\\data\\haarcascades\\haarcascade_frontalface_alt.xml";
CascadeClassifier face_cascade;
int iSize=10;//Gabor的scale
int main()
{
if( !face_cascade.load( face_cascade_name ) )
{
printf("[error] 无法加载级联分类器文件!\n");
return -1;
}
Mat testI = imread("man5.png");
if(testI.data ==0)
{
printf("[error] 没有图片\n");
return -5;
}
//提取人脸*****************************************************
Mat ROI= detectAndDisplay(testI);
//Gabor变换*************************************************************
normalize(ROI,ROI,1,0,CV_MINMAX,CV_32F);
Mat feature_Gabor;
feature_Gabor.release();
for(int i=0;i<8;i++)
{
for(int j=0;j<5;j++)
{
Mat M1= GaborFR::getRealGaborKernel(Size(iSize,iSize),
2*CV_PI,
i*CV_PI/8+CV_PI/2,
j,
1);
Mat M2 = GaborFR::getImagGaborKernel(Size(iSize,iSize),
2*CV_PI,
i*CV_PI/8+CV_PI/2,
j,
1);
//加了CV_PI/2才和大部分文献的图形一样,不知道为什么!
Mat outR,outI;
GaborFR::getFilterRealImagPart(ROI,M1,M2,outR,outI);
Mat M_Magnitude=GaborFR::getMagnitude(outR,outI);
normalize(M_Magnitude,M_Magnitude,0,1,CV_MINMAX,CV_32F);
Mat line= M_Magnitude.reshape(0,1);
feature_Gabor.push_back(line);
}
}
//PCA降维**************************************************
PCA pca(feature_Gabor, cv::Mat(), CV_PCA_DATA_AS_ROW,5);
Mat dst=pca.project(feature_Gabor) ;
Mat line =dst.reshape(0,1);
//SVM进行性别识别**************
CvSVM mySVM;
mySVM.load("SVM_PCA4.xml");//从XML文件读取训练好的SVM分类器模型
float response = mySVM.predict(line );
cout<< response< faces;
Mat frame_gray,ROI;
frame_gray= frame;
cvtColor( frame, frame_gray, CV_BGR2GRAY );
equalizeHist( frame_gray, frame_gray );
face_cascade.detectMultiScale( frame_gray, faces, 1.1, 2, 0|CV_HAAR_SCALE_IMAGE, Size(30, 30) );
for( int i = 0; i < faces.size(); i++ )
{
Point center( faces[i].x + faces[i].width*0.5, faces[i].y + faces[i].height*0.5 );
// ellipse( frame, center, Size( faces[i].width*0.5, faces[i].height*0.5), 0, 0, 360, Scalar( 255, 0, 255 ), 4, 8, 0 );
rectangle(frame, //图像.
faces[i].tl(), //矩形的一个顶点。
faces[i].br(), //矩形对角线上的另一个顶点
Scalar(0, 255, 0), //线条颜色 (RGB) 或亮度(灰度图像 )(grayscale image)
3); //组成矩形的线条的粗细程度。取负值时(如 CV_FILLED)函数绘制填充了色彩的矩形
ROI=frame_gray(Rect(faces[i].tl().x,faces[i].tl().y,faces[i].width,faces[i].height));
resize(ROI,ROI,Size(21,18),0,0,CV_INTER_LINEAR);
}
//namedWindow("qq",2);
//imshow( "qq", ROI );
imshow( "window_name", frame );
return ROI;
}
程序下载:http://download.csdn.net/detail/u012507022/9378791
(VS2010+opencv2.4.11)