svm原理:
以下轉自http://blog.csdn.net/yang_xian521/article/details/6969904
這次就先介紹一下機器學習中的一個常用算法SVM算法,即支持向量機Support Vector Machine(SVM),是一種有監督學習方法,更多介紹請見維基百科http://zh.wikipedia.org/wiki/SVM。
OpenCV開發SVM算法是基於LibSVM軟件包開發的,LibSVM是臺灣大學林智仁(Lin Chih-Jen)等開發設計的一個簡單、易於使用和快速有效的SVM模式識別與迴歸的軟件包。用OpenCV使用SVM算法的大概流程是
1)設置訓練樣本集
需要兩組數據,一組是數據的類別,一組是數據的向量信息。
2)設置SVM參數
利用CvSVMParams類實現類內的成員變量svm_type表示SVM類型:
CvSVM::C_SVC C-SVC
CvSVM::NU_SVC v-SVC
CvSVM::ONE_CLASS 一類SVM
CvSVM::EPS_SVR e-SVR
CvSVM::NU_SVR v-SVR
成員變量kernel_type表示核函數的類型:
CvSVM::LINEAR 線性:u‘v
CvSVM::POLY 多項式:(r*u'v + coef0)^degree
CvSVM::RBF RBF函數:exp(-r|u-v|^2)
CvSVM::SIGMOID sigmoid函數:tanh(r*u'v + coef0)
成員變量degree針對多項式核函數degree的設置,gamma針對多項式/rbf/sigmoid核函數的設置,coef0針對多項式/sigmoid核函數的設置,Cvalue爲損失函數,在C-SVC、e-SVR、v-SVR中有效,nu設置v-SVC、一類SVM和v-SVR參數,p爲設置e-SVR中損失函數的值,class_weightsC_SVC的權重,term_crit爲SVM訓練過程的終止條件。其中默認值degree = 0,gamma = 1,coef0 = 0,Cvalue = 1,nu = 0,p = 0,class_weights = 0
3)訓練SVM
調用CvSVM::train函數建立SVM模型,第一個參數爲訓練數據,第二個參數爲分類結果,最後一個參數即CvSVMParams
4)用這個SVM進行分類
調用函數CvSVM::predict實現分類
5)獲得支持向量
除了分類,也可以得到SVM的支持向量,調用函數CvSVM::get_support_vector_count獲得支持向量的個數,CvSVM::get_support_vector獲得對應的索引編號的支持向量。
實現代碼如下:
- // step 1:
- float labels[4] = {1.0, -1.0, -1.0, -1.0};
- Mat labelsMat(3, 1, CV_32FC1, labels);
- float trainingData[4][2] = { {501, 10}, {255, 10}, {501, 255}, {10, 501} };
- Mat trainingDataMat(3, 2, CV_32FC1, trainingData);
- // step 2:
- CvSVMParams params;
- params.svm_type = CvSVM::C_SVC;
- params.kernel_type = CvSVM::LINEAR;
- params.term_crit = cvTermCriteria(CV_TERMCRIT_ITER, 100, 1e-6);
- // step 3:
- CvSVM SVM;
- SVM.train(trainingDataMat, labelsMat, Mat(), Mat(), params);
- // step 4:
- Vec3b green(0, 255, 0), blue(255, 0, 0);
- for (int i=0; i<image.rows; i++)
- {
- for (int j=0; j<image.cols; j++)
- {
- Mat sampleMat = (Mat_<float>(1,2) << i,j);
- float response = SVM.predict(sampleMat);
- if (fabs(response-1.0) < 0.0001)
- {
- image.at<Vec3b>(j, i) = green;
- }
- else if (fabs(response+1.0) < 0.001)
- {
- image.at<Vec3b>(j, i) = blue;
- }
- }
- }
- // step 5:
- int c = SVM.get_support_vector_count();
- for (int i=0; i<c; i++)
- {
- const float* v = SVM.get_support_vector(i);
- }
// step 1:
float labels[4] = {1.0, -1.0, -1.0, -1.0};
Mat labelsMat(3, 1, CV_32FC1, labels);
float trainingData[4][2] = { {501, 10}, {255, 10}, {501, 255}, {10, 501} };
Mat trainingDataMat(3, 2, CV_32FC1, trainingData);
// step 2:
CvSVMParams params;
params.svm_type = CvSVM::C_SVC;
params.kernel_type = CvSVM::LINEAR;
params.term_crit = cvTermCriteria(CV_TERMCRIT_ITER, 100, 1e-6);
// step 3:
CvSVM SVM;
SVM.train(trainingDataMat, labelsMat, Mat(), Mat(), params);
// step 4:
Vec3b green(0, 255, 0), blue(255, 0, 0);
for (int i=0; i<image.rows; i++)
{
for (int j=0; j<image.cols; j++)
{
Mat sampleMat = (Mat_<float>(1,2) << i,j);
float response = SVM.predict(sampleMat);
if (fabs(response-1.0) < 0.0001)
{
image.at<Vec3b>(j, i) = green;
}
else if (fabs(response+1.0) < 0.001)
{
image.at<Vec3b>(j, i) = blue;
}
}
}
// step 5:
int c = SVM.get_support_vector_count();
for (int i=0; i<c; i++)
{
const float* v = SVM.get_support_vector(i);
}