欢迎转载,请注明出处;本人能力有限,错误在所难免,欢迎指导
基于前两博文,已经训练出一个性别分类器。那就应该运用这个分类器进行性别分类。
这个测试过程与训练过程一样。只不过,训练时,是大批量的处理样本数据数据。测试过程,针对需要识别的图像进行处理。
- 首先进行人脸识别,即在图像中找出人脸,把人脸区域提取出来。
- 第二步,运用Gabor小波对人脸提取特征。
- 第三步,运用PCA对Gabor提取的特征进行降维处理。
- 最后,把降维后特征,输入训练好的分类器,得出分类结果。
结果显示:
结果分析:
训练过程man样本 409,woman样本287。其实,对于机器学习来说,这些样本还是很少的。在进行测试时,6个man图像可以正确识别。woman图像识别过程出现了错误识别。因为样本图片都是老外,而且人数有限。对其他图片效果应该不是很好。
本人分析的主要原因有两点:1)在训练过程,Gabor小波、PCA降维过程的参数选取没有进行严格的测试;
2)训练样本太少,而且样本中就那几个人的脸。可以增加训练样本的数量。
最后还得提一点,由于训练过程运算量大。训练600多个样本,运行了应该有半个小时。
main.cpp (Gabor类文件同(2))
1 #include <opencv2/opencv.hpp> 2 #include <opencv2/highgui/highgui.hpp> 3 #include <opencv2/ml/ml.hpp> 4 #include "GaborFR.h" 5 using namespace cv; 6 using namespace std; 7 Mat detectAndDisplay( Mat); 8 //加载Opencv自带人脸识别级联分类器文件 9 string face_cascade_name ="D:\\Program Files\\opencv\\sources\\data\\haarcascades\\haarcascade_frontalface_alt.xml"; 10 CascadeClassifier face_cascade; 11 int iSize=10;//Gabor的scale 12 int main() 13 { 14 if( !face_cascade.load( face_cascade_name ) ) 15 { 16 printf("[error] 无法加载级联分类器文件!\n"); 17 return -1; 18 } 19 20 Mat testI = imread("man5.png"); 21 if(testI.data ==0) 22 { 23 printf("[error] 没有图片\n"); 24 return -5; 25 } 26 //提取人脸***************************************************** 27 Mat ROI= detectAndDisplay(testI); 28 //Gabor变换************************************************************* 29 normalize(ROI,ROI,1,0,CV_MINMAX,CV_32F); 30 Mat feature_Gabor; 31 feature_Gabor.release(); 32 for(int i=0;i<8;i++) 33 { 34 35 for(int j=0;j<5;j++) 36 { 37 Mat M1= GaborFR::getRealGaborKernel(Size(iSize,iSize), 38 2*CV_PI, 39 i*CV_PI/8+CV_PI/2, 40 j, 41 1); 42 Mat M2 = GaborFR::getImagGaborKernel(Size(iSize,iSize), 43 2*CV_PI, 44 i*CV_PI/8+CV_PI/2, 45 j, 46 1); 47 //加了CV_PI/2才和大部分文献的图形一样,不知道为什么! 48 Mat outR,outI; 49 GaborFR::getFilterRealImagPart(ROI,M1,M2,outR,outI); 50 Mat M_Magnitude=GaborFR::getMagnitude(outR,outI); 51 normalize(M_Magnitude,M_Magnitude,0,1,CV_MINMAX,CV_32F); 52 Mat line= M_Magnitude.reshape(0,1); 53 feature_Gabor.push_back(line); 54 55 } 56 } 57 58 //PCA降维************************************************** 59 PCA pca(feature_Gabor, cv::Mat(), CV_PCA_DATA_AS_ROW,5); 60 Mat dst=pca.project(feature_Gabor) ; 61 Mat line =dst.reshape(0,1); 62 63 //SVM进行性别识别************** 64 CvSVM mySVM; 65 mySVM.load("SVM_PCA4.xml");//从XML文件读取训练好的SVM分类器模型 66 float response = mySVM.predict(line ); 67 68 cout<< response<<endl; 69 if(response==1) 70 cout<<"boy"<<endl; 71 if(response==-1) 72 cout<<"girl"<<endl; 73 waitKey(0); 74 system("pause"); 75 } 76 77 78 Mat detectAndDisplay( Mat frame) 79 { 80 std::vector<Rect> faces; 81 Mat frame_gray,ROI; 82 frame_gray= frame; 83 cvtColor( frame, frame_gray, CV_BGR2GRAY ); 84 equalizeHist( frame_gray, frame_gray ); 85 86 face_cascade.detectMultiScale( frame_gray, faces, 1.1, 2, 0|CV_HAAR_SCALE_IMAGE, Size(30, 30) ); 87 88 for( int i = 0; i < faces.size(); i++ ) 89 { 90 Point center( faces[i].x + faces[i].width*0.5, faces[i].y + faces[i].height*0.5 ); 91 // ellipse( frame, center, Size( faces[i].width*0.5, faces[i].height*0.5), 0, 0, 360, Scalar( 255, 0, 255 ), 4, 8, 0 ); 92 rectangle(frame, //图像. 93 faces[i].tl(), //矩形的一个顶点。 94 faces[i].br(), //矩形对角线上的另一个顶点 95 Scalar(0, 255, 0), //线条颜色 (RGB) 或亮度(灰度图像 )(grayscale image) 96 3); //组成矩形的线条的粗细程度。取负值时(如 CV_FILLED)函数绘制填充了色彩的矩形 97 ROI=frame_gray(Rect(faces[i].tl().x,faces[i].tl().y,faces[i].width,faces[i].height)); 98 resize(ROI,ROI,Size(21,18),0,0,CV_INTER_LINEAR); 99 } 100 101 //namedWindow("qq",2); 102 //imshow( "qq", ROI ); 103 104 imshow( "window_name", frame ); 105 return ROI; 106 }
时间: 2024-10-13 00:35:20