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、人脸识别类
详细的可以参考opencv实践之路
不需要知道在哪个头文件中,直接#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);
令人欣喜的是,不仅仅是人脸识别,其他目的的训练和预测也是可以的。