-2
我尝试过使用支持向量机进行人脸识别,下面是我用于培训和测试的代码。问题是我没有得到准确的结果,有时我总是将预测值作为“0”。使用支持向量机的人脸识别
有人能帮助我解决正确的SVM参数。
培训代码:
static void read_csv(const string& filename, vector<Mat>& images, vector<int>& label, char separator = ';') {
std::ifstream file(filename.c_str(), ifstream::in);
if (!file) {
string error_message = "No valid input file was given, please check the given filename.";
CV_Error(CV_StsBadArg, error_message);
}
string line, path, classlabel;
while (getline(file, line)) {
stringstream liness(line);
getline(liness, path, separator);
getline(liness, classlabel);
if(!path.empty() && !classlabel.empty()) {
Mat testimage = imread(path, 0);
imshow("testimage", testimage);
waitKey(10);
images.push_back(testimage);
label.push_back(atoi(classlabel.c_str()));
}
}
}
int svm()
{
// Data for visual representation
string fn_csv = string("/home/resize.csv");
// These vectors hold the images and corresponding labels.
vector<Mat> images;
vector<int> label;
// Read in the data. This can fail if no valid
// input filename is given.
try {
read_csv(fn_csv, images,label);
} catch (cv::Exception& e) {
cerr << "Error opening file \"" << fn_csv << "\". Reason: " << e.msg << endl;
// nothing more we can do
exit(1);
}
// Set up SVM's parameters
Mat labelsMat(label.size(), 1, CV_32FC1);
Mat trainingDataMat(images.size(),70*70, CV_32FC1);
//iterating through the rows
int c=0;int d;
for (int j = 0; j <label.size(); j++) {
//iteration through the columns
d=0;
c++;
labelsMat.at<float>(j,0)=float(label[j]);
for (int r = 0;r<images[j].rows; r++) {
//iterating through the rows
for (int c = 0; c <images[j].cols; c++) {
trainingDataMat.at<float>(j,d++) = images[j].at<uchar>(r,c);
}
}
}
//imshow("first",images[7]);
cout<<"labels"<<labelsMat<<std::endl;
cout<<"labels size"<<c<<std::endl;
// CvSVMParams params;
SVMParams params = SVMParams();
params.svm_type = SVM::C_SVC;
params.kernel_type = SVM::LINEAR;
params.degree = 3.43; // for poly
params.gamma = 0.00225; // for poly/rbf/sigmoid
params.coef0 = 19.6; // for poly/sigmoid
params.C = 0.5; // for CV_SVM_C_SVC , CV_SVM_EPS_SVR and CV_SVM_NU_SVR
params.nu = 0.0; // for CV_SVM_NU_SVC , CV_SVM_ONE_CLASS , and CV_SVM_NU_SVR
params.p = 0.0; // for CV_SVM_EPS_SVR
params.class_weights = NULL; // for CV_SVM_C_SVC
params.term_crit.type = CV_TERMCRIT_ITER | CV_TERMCRIT_EPS;
params.term_crit.max_iter = 1000;
params.term_crit.epsilon = 1e-6;
// Train the SVM
CvSVM SVM;
SVM.train(trainingDataMat, labelsMat, Mat(), Mat(), params);
// cout<<"train row" <<trainingDataMat.rowRange()<<"cols"<<trainingDataMat.cols<<std::endl;
SVM.save("/home/test.yml");
return 0;
}
预测代码:
int svm_test()
{
// Train the SVM
CvSVM SVM;
Mat test=imread("/home/n2.jpg",0);
// cout<<"image size"<<(float(test.size))<<std::endl;
Mat test_mat(1,test.cols*test.rows,CV_32FC1);
int ii1=0;
for (int i1 = 0; i1<test.rows; i1++) {
//iterating through the rows
for (int j1 = 0; j1 < test.cols; j1++) {
//iteration through the columns
test_mat.at<float>(0,ii1++) = test.at<uchar>(i1,j1);
// labels.at<float>(filenum,1);//=float(filenum);
}
}
// waitKey(0);
SVM.load("/home/smile.yml");
cout<<"preditction value"<<SVM.predict(test_mat)<<std::endl;
return 0;
}