1. 程式人生 > >opencv knn,svm,ann,人臉識別類的使用總結

opencv knn,svm,ann,人臉識別類的使用總結

1、 knn

需要引用的標頭檔案  #include <opencv2/ml/ml.hpp>

用到的opencv類:KNearest   *knn;         

得到訓練資料和相應的標記:trainData,將每一個訓練矩陣歸一化為相同的大小,假如為128行128列,則將其轉換為1行128*128列存入trainData中,假如有10個分組,每組中50個樣本,則最後得到的trainData為500行128*128列,trainClasses為500行1列。trainData和trainClasses都為CV_32FC1型別的矩陣

訓練資料:knn = new KNearest(trainData, trainClasses, Mat(), false, K);  //其中,K表示最大鄰居個數,推薦取值為5

預測:float result = knn->find_nearest(img, K, tem1, nearest, tem2);   //此行程式碼之前,僅需Mat tem1, tem2;即可

唯一遺憾的是,我現在還沒找到可以儲存訓練後資料的方式。


2、svm

需要引用的標頭檔案  #include <opencv2/ml/ml.hpp>

第一步:定義引數

CvSVMParams params;
params.svm_type = CvSVM::C_SVC;
params.kernel_type = CvSVM::LINEAR;
params.term_crit = cvTermCriteria(CV_TERMCRIT_ITER, 100, 1e-6);
或者
CvSVMParams SVM_params;  // CvSVMParams結構用於定義基本引數
SVM_params.svm_type = CvSVM::C_SVC;		// SVM型別
SVM_params.kernel_type = CvSVM::LINEAR; // 不做對映
SVM_params.degree = 0;
SVM_params.gamma = 1;
SVM_params.coef0 = 0;
SVM_params.C = 1;
SVM_params.nu = 0;
SVM_params.p = 0;
SVM_params.term_crit = cvTermCriteria(CV_TERMCRIT_ITER, 1000, 0.01);
引數的詳細意義,可以日後好好探究下

第二步:得到訓練資料和相應的標記,其mat矩陣儲存方式 同knn

第三步:建立svm類,並訓練

CvSVM SVM;
SVM.train(trainingDataMat, labelsMat, Mat(), Mat(), params);
或者一行程式碼就可以搞定
CvSVM svmClassifier(SVM_TrainingData, SVM_Classes, Mat(), Mat(), SVM_params);
第四步:預測分類

int response = (int)svmClassifier.predict(p);//其中,p為一行多列的Mat矩陣


3、ann(神經網路)

神經網路的簡單用法,可以參考ann簡單使用示例

需要引用的標頭檔案  #include <opencv2/ml/ml.hpp>

第一步:定義引數

CvANN_MLP  ann;
Mat layers(1, 3, CV_32SC1);
layers.at<int>(0) = TrainData.cols;//對應訓練資料矩陣的列數
layers.at<int>(1) = nNeruns;//網路層數
layers.at<int>(2) = trainClasses.cols;//對應標記矩陣的列數
ann.create(layers, CvANN_MLP::SIGMOID_SYM, 1, 1);
CvANN_MLP_TrainParams params;
params.train_method = CvANN_MLP_TrainParams::BACKPROP;
params.bp_dw_scale = 0.1;
params.bp_moment_scale = 0.1;
或者(引數的具體意義,現在還沒搞懂,推薦使用上面的引數)
params.train_method=CvANN_MLP_TrainParams::RPROP;
params.rp_dw0 = 0.1; 
params.rp_dw_plus = 1.2; 
params.rp_dw_minus = 0.5;
params.rp_dw_min = FLT_EPSILON; 
params.rp_dw_max = 50.;

第二步:得到訓練資料和相應的標記,其中標記矩陣可以是多列的,不一定是knn中總結的多行一列

第三步:訓練資料

ann.train(TrainData, trainClasses, Mat(), Mat(), params);

第四步:預測
ann.predict(features, Predict_result);
//其中,features為一行多列的資料矩陣,列數對應TrainData, Predict_result為一行多列或者一行一列的矩陣,對應trainClass。最後從Predict_result中判斷其屬於哪一類

4、人臉識別類

不需要知道在哪個標頭檔案中,直接#include<opencv2\opencv.hpp>  即可

OpenCV 自帶了三個人臉識別演算法:Eigenfaces,Fisherfaces 和區域性二值模式直方圖 (LBPH)

第一步:Ptr<FaceRecognizer> model;

第二步:得到訓練資料和相應的標記, vector<Mat> images;vector<int> labels;  //這個比上面的knn,svm,ann都簡單

第三步:

model = createEigenFaceRecognizer();
model->train(images, labels);
model->save("MyFacePCAModel.xml");//so easy

或者

model = createFisherFaceRecognizer();
model->train(images, labels);
model->save("MyFaceFisherModel.xml");

或者

model = createLBPHFaceRecognizer();
model->train(images, labels);
model->save("MyFaceLBPHModel.xml");

如果已經儲存了訓練好的資料,可以:model->load("MyFacePCAModel.xml");

第四步:int result = model->predict(src);

令人欣喜的是,不僅僅是人臉識別,其他目的的訓練和預測也是可以的。