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);
令人欣喜的是,不僅僅是人臉識別,其他目的的訓練和預測也是可以的。