|
學(xué)習(xí)SVM,首先通過(guò)http://zh./wiki/SVM,
再通過(guò)博客http://blog.csdn.net/yang_xian521/article/details/6969904
OpenCV開(kāi)發(fā)SVM算法是基于LibSVM軟件包開(kāi)發(fā)的,LibSVM是臺(tái)灣大學(xué)林智仁(Lin Chih-Jen)等開(kāi)發(fā)設(shè)計(jì)的一個(gè)簡(jiǎn)單、易于使用和快速有效的SVM模式識(shí)別與回歸的軟件包。用OpenCV使用SVM算法的大概流程是
1)設(shè)置訓(xùn)練樣本集
需要兩組數(shù)據(jù),一組是數(shù)據(jù)的類(lèi)別,一組是數(shù)據(jù)的向量信息。
2)設(shè)置SVM參數(shù)
利用CvSVMParams類(lèi)實(shí)現(xiàn)類(lèi)內(nèi)的成員變量svm_type表示SVM類(lèi)型:
CvSVM::C_SVC C-SVC
CvSVM::NU_SVC v-SVC
CvSVM::ONE_CLASS 一類(lèi)SVM
CvSVM::EPS_SVR e-SVR
CvSVM::NU_SVR v-SVR
成員變量kernel_type表示核函數(shù)的類(lèi)型:
CvSVM::LINEAR 線性:u‘v
CvSVM::POLY 多項(xiàng)式:(r*u'v + coef0)^degree
CvSVM::RBF RBF函數(shù):exp(-r|u-v|^2)
CvSVM::SIGMOID sigmoid函數(shù):tanh(r*u'v + coef0)
成員變量degree針對(duì)多項(xiàng)式核函數(shù)degree的設(shè)置,gamma針對(duì)多項(xiàng)式/rbf/sigmoid核函數(shù)的設(shè)置,coef0針對(duì)多項(xiàng)式/sigmoid核函數(shù)的設(shè)置,Cvalue為損失函數(shù),在C-SVC、e-SVR、v-SVR中有效,nu設(shè)置v-SVC、一類(lèi)SVM和v-SVR參數(shù),p為設(shè)置e-SVR中損失函數(shù)的值,class_weightsC_SVC的權(quán)重,term_crit為SVM訓(xùn)練過(guò)程的終止條件。其中默認(rèn)值degree = 0,gamma = 1,coef0 = 0,Cvalue = 1,nu = 0,p = 0,class_weights = 0
3)訓(xùn)練SVM
調(diào)用CvSVM::train函數(shù)建立SVM模型,第一個(gè)參數(shù)為訓(xùn)練數(shù)據(jù),第二個(gè)參數(shù)為分類(lèi)結(jié)果,最后一個(gè)參數(shù)即CvSVMParams
4)用這個(gè)SVM進(jìn)行分類(lèi)
調(diào)用函數(shù)CvSVM::predict實(shí)現(xiàn)分類(lèi)
5)獲得支持向量
除了分類(lèi),也可以得到SVM的支持向量,調(diào)用函數(shù)CvSVM::get_support_vector_count獲得支持向量的個(gè)數(shù),CvSVM::get_support_vector獲得對(duì)應(yīng)的索引編號(hào)的支持向量。
實(shí)現(xiàn)代碼如下:運(yùn)行步驟
- // 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);
- }
實(shí)驗(yàn)代碼1:顏色分類(lèi)
- //利用SVM解決2維空間向量的3級(jí)分類(lèi)問(wèn)題
- #include "stdafx.h"
- #include "cv.h"
- #include "highgui.h"
- #include <ML.H>
- #include <TIME.H>
-
- #include <CTYPE.H>
-
- #include <IOSTREAM>
- using namespace std;
- int main(int argc, char **argv)
- {
- int size = 400; //圖像的長(zhǎng)度和寬度
- const int s = 1000; //試驗(yàn)點(diǎn)個(gè)數(shù)(可更改?。。?nbsp;
- int i, j, sv_num;
- IplImage *img;
- CvSVM svm = CvSVM(); //★★★
- CvSVMParams param;
- CvTermCriteria criteria;//停止迭代的標(biāo)準(zhǔn)
- CvRNG rng = cvRNG(time(NULL));
- CvPoint pts[s]; //定義1000個(gè)點(diǎn)
- float data[s*2]; //點(diǎn)的坐標(biāo)
- int res[s]; //點(diǎn)的所屬類(lèi)
- CvMat data_mat, res_mat;
- CvScalar rcolor;
- const float *support;
- // (1)圖像區(qū)域的確保和初始化
- img= cvCreateImage(cvSize(size, size), IPL_DEPTH_8U, 3);
- cvZero(img);
- //確保畫(huà)像區(qū)域,并清0(用黑色作初始化處理)。
-
- // (2)學(xué)習(xí)數(shù)據(jù)的生成
- for (i= 0; i< s; i++) {
- pts[i].x= cvRandInt(&rng) % size; //用隨機(jī)整數(shù)賦值
- pts[i].y= cvRandInt(&rng) % size;
- if (pts[i].y> 50 * cos(pts[i].x* CV_PI/ 100) + 200) {
- cvLine(img, cvPoint(pts[i].x- 2, pts[i].y- 2), cvPoint(pts[i].x+ 2, pts[i].y+ 2), CV_RGB(255, 0, 0));
- cvLine(img, cvPoint(pts[i].x+ 2, pts[i].y- 2), cvPoint(pts[i].x- 2, pts[i].y+ 2), CV_RGB(255, 0, 0));
- res[i] = 1;
- }
- else {
- if (pts[i].x> 200) {
- cvLine(img, cvPoint(pts[i].x- 2, pts[i].y- 2), cvPoint(pts[i].x+ 2, pts[i].y+ 2), CV_RGB(0, 255, 0));
- cvLine(img, cvPoint(pts[i].x+ 2, pts[i].y- 2), cvPoint(pts[i].x- 2, pts[i].y+ 2), CV_RGB(0, 255, 0));
- res[i] = 2;
- }
- else {
- cvLine(img, cvPoint(pts[i].x- 2, pts[i].y- 2), cvPoint(pts[i].x+ 2, pts[i].y+ 2), CV_RGB(0, 0, 255));
- cvLine(img, cvPoint(pts[i].x+ 2, pts[i].y- 2), cvPoint(pts[i].x- 2, pts[i].y+ 2), CV_RGB(0, 0, 255));
- res[i] = 3;
- }
- }
- }
- //生成2維隨機(jī)訓(xùn)練數(shù)據(jù),并將其值放在CvPoint數(shù)據(jù)類(lèi)型的數(shù)組pts[ ]中。
-
- // (3)學(xué)習(xí)數(shù)據(jù)的顯示
- cvNamedWindow("SVM", CV_WINDOW_AUTOSIZE);
- cvShowImage("SVM", img);
- cvWaitKey(0);
-
- // (4)學(xué)習(xí)參數(shù)的生成
- for (i= 0; i< s; i++) {
- data[i* 2] = float (pts[i].x) / size;
- data[i* 2 + 1] = float (pts[i].y) / size;
- }
- cvInitMatHeader(&data_mat, s, 2, CV_32FC1, data);
- cvInitMatHeader(&res_mat, s, 1, CV_32SC1, res);
- criteria= cvTermCriteria(CV_TERMCRIT_EPS, 1000, FLT_EPSILON);
- param= CvSVMParams (CvSVM::C_SVC, CvSVM::RBF, 10.0, 8.0, 1.0, 10.0, 0.5, 0.1, NULL, criteria);
- /*
- SVM種類(lèi):CvSVM::C_SVC
- Kernel的種類(lèi):CvSVM::RBF
- degree:10.0(此次不使用)
- gamma:8.0
- coef0:1.0(此次不使用)
- C:10.0
- nu:0.5(此次不使用)
- p:0.1(此次不使用)
- 然后對(duì)訓(xùn)練數(shù)據(jù)正規(guī)化處理,并放在CvMat型的數(shù)組里。
- */
-
-
- //☆☆☆☆☆☆☆☆☆(5)SVM學(xué)習(xí)☆☆☆☆☆☆☆☆☆☆☆☆
- svm.train(&data_mat, &res_mat, NULL, NULL, param);//☆
- //☆☆利用訓(xùn)練數(shù)據(jù)和確定的學(xué)習(xí)參數(shù),進(jìn)行SVM學(xué)習(xí)☆☆☆☆
-
- // (6)學(xué)習(xí)結(jié)果的繪圖
- for (i= 0; i< size; i++) {
- for (j= 0; j< size; j++) {
- CvMat m;
- float ret = 0.0;
- float a[] = { float (j) / size, float (i) / size };
- cvInitMatHeader(&m, 1, 2, CV_32FC1, a);
- ret= svm.predict(&m);
- switch ((int) ret) {
- case 1:
- rcolor= CV_RGB(100, 0, 0);
- break;
- case 2:
- rcolor= CV_RGB(0, 100, 0);
- break;
- case 3:
- rcolor= CV_RGB(0, 0, 100);
- break;
- }
- cvSet2D(img, i, j, rcolor);
- }
- }
- //為了顯示學(xué)習(xí)結(jié)果,通過(guò)輸入圖像區(qū)域的所有像素(特征向量)并進(jìn)行分類(lèi)。然后對(duì)輸入像素用所屬等級(jí)的顏色繪圖。
-
- // (7)訓(xùn)練數(shù)據(jù)的再繪制
- for (i= 0; i< s; i++) {
- CvScalar rcolor;
- switch (res[i]) {
- case 1:
- rcolor= CV_RGB(255, 0, 0);
- break;
- case 2:
- rcolor= CV_RGB(0, 255, 0);
- break;
- case 3:
- rcolor= CV_RGB(0, 0, 255);
- break;
- }
- cvLine(img, cvPoint(pts[i].x- 2, pts[i].y- 2), cvPoint(pts[i].x+ 2, pts[i].y+ 2), rcolor);
- cvLine(img, cvPoint(pts[i].x+ 2, pts[i].y- 2), cvPoint(pts[i].x- 2, pts[i].y+ 2), rcolor);
- }
- //將訓(xùn)練數(shù)據(jù)在結(jié)果圖像上重復(fù)的繪制出來(lái)。
-
- // (8)支持向量的繪制
- sv_num= svm.get_support_vector_count();
- for (i= 0; i< sv_num; i++) {
- support = svm.get_support_vector(i);
- cvCircle(img, cvPoint((int) (support[0] * size), (int) (support[1] * size)), 5, CV_RGB(200, 200, 200));
- }
- //用白色的圓圈對(duì)支持向量作標(biāo)記。
-
- // (9)圖像的顯示
- cvNamedWindow("SVM", CV_WINDOW_AUTOSIZE);
- cvShowImage("SVM", img);
- cvWaitKey(0);
- cvDestroyWindow("SVM");
- cvReleaseImage(&img);
- return 0;
- //顯示實(shí)際處理結(jié)果的圖像,直到某個(gè)鍵被按下為止。
- }
實(shí)驗(yàn)代碼2:用MIT人臉庫(kù)檢測(cè),效果實(shí)在不好,檢測(cè)結(jié)果全是人臉或者全都不是人臉。原因應(yīng)該是圖像檢測(cè)沒(méi)有做好應(yīng)該用HoG等特征首先檢測(cè),在進(jìn)行分類(lèi)訓(xùn)練,不特征不明顯,肯定分類(lèi)效果并不好。
- //////////////////////////////////////////////////////////////////////////
- // File Name: pjSVM.cpp
- // Author: easyfov(easyfov@gmail.com)
- // Company: Lida Optical and Electronic Co.,Ltd.
- //http://apps.hi.baidu.com/share/detail/32719017
- //////////////////////////////////////////////////////////////////////////
-
- #include <cv.h>
- #include <highgui.h>
- #include <ml.h>
-
- #include <iostream>
- #include <fstream>
- #include <string>
- #include <vector>
- using namespace std;
-
- #define WIDTH 20
- #define HEIGHT 20
-
- int main( /*int argc, char** argv*/ )
- {
- vector<string> img_path;
- vector<int> img_catg;
- int nLine = 0;
- string buf;
- ifstream svm_data( "E:/SVM_DATA.txt" );
-
- while( svm_data )
- {
- if( getline( svm_data, buf ) )
- {
- nLine ++;
- if( nLine % 2 == 0 )
- {
- img_catg.push_back( atoi( buf.c_str() ) );//atoi將字符串轉(zhuǎn)換成整型,標(biāo)志(0,1)
- }
- else
- {
- img_path.push_back( buf );//圖像路徑
- }
- }
- }
- svm_data.close();//關(guān)閉文件
-
- CvMat *data_mat, *res_mat;
- int nImgNum = nLine / 2; //讀入樣本數(shù)量
- ////樣本矩陣,nImgNum:橫坐標(biāo)是樣本數(shù)量, WIDTH * HEIGHT:樣本特征向量,即圖像大小
- data_mat = cvCreateMat( nImgNum, WIDTH * HEIGHT, CV_32FC1 );
- cvSetZero( data_mat );
- //類(lèi)型矩陣,存儲(chǔ)每個(gè)樣本的類(lèi)型標(biāo)志
- res_mat = cvCreateMat( nImgNum, 1, CV_32FC1 );
- cvSetZero( res_mat );
-
- IplImage *srcImg, *sampleImg;
- float b;
- DWORD n;
-
- for( string::size_type i = 0; i != img_path.size(); i++ )
- {
- srcImg = cvLoadImage( img_path[i].c_str(), CV_LOAD_IMAGE_GRAYSCALE );
- if( srcImg == NULL )
- {
- cout<<" can not load the image: "<<img_path[i].c_str()<<endl;
- continue;
- }
-
- cout<<" processing "<<img_path[i].c_str()<<endl;
-
- sampleImg = cvCreateImage( cvSize( WIDTH, HEIGHT ), IPL_DEPTH_8U, 1 );//樣本大小(WIDTH, HEIGHT)
- cvResize( srcImg, sampleImg );//改變圖像大小
-
- cvSmooth( sampleImg, sampleImg ); //降噪
- //生成訓(xùn)練數(shù)據(jù)
- n = 0;
- for( int ii = 0; ii < sampleImg->height; ii++ )
- {
- for( int jj = 0; jj < sampleImg->width; jj++, n++ )
- {
- b = (float)((int)((uchar)( sampleImg->imageData + sampleImg->widthStep * ii + jj )) / 255.0 );
- cvmSet( data_mat, (int)i, n, b );
- }
- }
- cvmSet( res_mat, i, 0, img_catg[i] );
- cout<<" end processing "<<img_path[i].c_str()<<" "<<img_catg[i]<<endl;
- }
-
-
- CvSVM svm = CvSVM();
- CvSVMParams param;
- CvTermCriteria criteria;
- criteria = cvTermCriteria( CV_TERMCRIT_EPS, 1000, FLT_EPSILON );
- param = CvSVMParams( CvSVM::C_SVC, CvSVM::RBF, 10.0, 0.09, 1.0, 10.0, 0.5, 1.0, NULL, criteria );
- /*
- SVM種類(lèi):CvSVM::C_SVC
- Kernel的種類(lèi):CvSVM::RBF
- degree:10.0(此次不使用)
- gamma:8.0
- coef0:1.0(此次不使用)
- C:10.0
- nu:0.5(此次不使用)
- p:0.1(此次不使用)
- 然后對(duì)訓(xùn)練數(shù)據(jù)正規(guī)化處理,并放在CvMat型的數(shù)組里。
- */
- //☆☆☆☆☆☆☆☆☆(5)SVM學(xué)習(xí)☆☆☆☆☆☆☆☆☆☆☆☆
- svm.train( data_mat, res_mat, NULL, NULL, param );
- //☆☆利用訓(xùn)練數(shù)據(jù)和確定的學(xué)習(xí)參數(shù),進(jìn)行SVM學(xué)習(xí)☆☆☆☆
- svm.save( "SVM_DATA.xml" );
-
-
- //檢測(cè)樣本
- IplImage *tst, *tst_tmp;
- vector<string> img_tst_path;
- ifstream img_tst( "E:/SVM_TEST.txt" );
- while( img_tst )
- {
- if( getline( img_tst, buf ) )
- {
- img_tst_path.push_back( buf );
- }
- }
- img_tst.close();
-
- CvMat *tst_mat = cvCreateMat( 1, WIDTH*HEIGHT, CV_32FC1 );
- char line[512];
- ofstream predict_txt( "SVM_PREDICT.txt" );
- for( string::size_type j = 0; j != img_tst_path.size(); j++ )
- {
- tst = cvLoadImage( img_tst_path[j].c_str(), CV_LOAD_IMAGE_GRAYSCALE );
- if( tst == NULL )
- {
- cout<<" can not load the image: "<<img_tst_path[j].c_str()<<endl;
- continue;
- }
- tst_tmp = cvCreateImage( cvSize( WIDTH, HEIGHT ), IPL_DEPTH_8U, 1 );
- cvResize( tst, tst_tmp );
- cvSmooth( tst_tmp, tst_tmp );
- n = 0;
- for(int ii = 0; ii < tst_tmp->height; ii++ )
- {
- for(int jj = 0; jj < tst_tmp->width; jj++, n++ )
- {
- b = (float)(((int)((uchar)tst_tmp->imageData+tst_tmp->widthStep*ii+jj))/255.0);
- cvmSet( tst_mat, 0, n, (double)b );
- }
- }
-
- int ret = svm.predict( tst_mat );
- sprintf( line, "%s %d\r\n", img_tst_path[j].c_str(), ret );
- predict_txt<<line;
- }
- predict_txt.close();
-
- cvReleaseImage( &srcImg );
- cvReleaseImage( &sampleImg );
- cvReleaseImage( &tst );
- cvReleaseImage( &tst_tmp );
- cvReleaseMat( &data_mat );
- cvReleaseMat( &res_mat );
-
- return 0;
- }
其中
G:/program/pjSVM/face/1.png 0 G:/program/pjSVM/face/2.png 0 G:/program/pjSVM/face/3.png 0 G:/program/pjSVM/face/4.png 0 G:/program/pjSVM/face/5.png 0 G:/program/pjSVM/face/6.png 0 G:/program/pjSVM/face/7.png 0 G:/program/pjSVM/face/8.png 0 G:/program/pjSVM/face/9.png 0 G:/program/pjSVM/face/10.png 0 G:/program/pjSVM/face/11.png 0 G:/program/pjSVM/face/12.png 0 G:/program/pjSVM/face/13.png 0 G:/program/pjSVM/face/14.png 0 G:/program/pjSVM/face/15.png 1 G:/program/pjSVM/face/16.png 1 G:/program/pjSVM/face/17.png 1 G:/program/pjSVM/face/18.png 1 G:/program/pjSVM/face/19.png 1 G:/program/pjSVM/face/20.png 1 G:/program/pjSVM/face/21.png 1 G:/program/pjSVM/face/22.png 1 G:/program/pjSVM/face/23.png 1 G:/program/pjSVM/face/24.png 1 G:/program/pjSVM/face/25.png 1 G:/program/pjSVM/face/26.png 1 G:/program/pjSVM/face/27.png 1 G:/program/pjSVM/face/28.png 1 G:/program/pjSVM/face/29.png 1 G:/program/pjSVM/face/30.png
1
SVM_TEST.txt中內(nèi)容如下:
G:/program/pjSVM/try_face/5.png G:/program/pjSVM/try_face/9.png G:/program/pjSVM/try_face/11.png G:/program/pjSVM/try_face/15.png G:/program/pjSVM/try_face/2.png G:/program/pjSVM/try_face/30.png G:/program/pjSVM/try_face/17.png G:/program/pjSVM/try_face/21.png G:/program/pjSVM/try_face/24.png G:/program/pjSVM/try_face/27.png
PS:txt操作簡(jiǎn)單方式:http://blog.csdn.net/lytwell/article/details/6029503
學(xué)習(xí)SVM,首先通過(guò)http://zh./wiki/SVM,
再通過(guò)博客http://blog.csdn.net/yang_xian521/article/details/6969904
OpenCV開(kāi)發(fā)SVM算法是基于LibSVM軟件包開(kāi)發(fā)的,LibSVM是臺(tái)灣大學(xué)林智仁(Lin Chih-Jen)等開(kāi)發(fā)設(shè)計(jì)的一個(gè)簡(jiǎn)單、易于使用和快速有效的SVM模式識(shí)別與回歸的軟件包。用OpenCV使用SVM算法的大概流程是
1)設(shè)置訓(xùn)練樣本集
需要兩組數(shù)據(jù),一組是數(shù)據(jù)的類(lèi)別,一組是數(shù)據(jù)的向量信息。
2)設(shè)置SVM參數(shù)
利用CvSVMParams類(lèi)實(shí)現(xiàn)類(lèi)內(nèi)的成員變量svm_type表示SVM類(lèi)型:
CvSVM::C_SVC C-SVC
CvSVM::NU_SVC v-SVC
CvSVM::ONE_CLASS 一類(lèi)SVM
CvSVM::EPS_SVR e-SVR
CvSVM::NU_SVR v-SVR
成員變量kernel_type表示核函數(shù)的類(lèi)型:
CvSVM::LINEAR 線性:u‘v
CvSVM::POLY 多項(xiàng)式:(r*u'v + coef0)^degree
CvSVM::RBF RBF函數(shù):exp(-r|u-v|^2)
CvSVM::SIGMOID sigmoid函數(shù):tanh(r*u'v + coef0)
成員變量degree針對(duì)多項(xiàng)式核函數(shù)degree的設(shè)置,gamma針對(duì)多項(xiàng)式/rbf/sigmoid核函數(shù)的設(shè)置,coef0針對(duì)多項(xiàng)式/sigmoid核函數(shù)的設(shè)置,Cvalue為損失函數(shù),在C-SVC、e-SVR、v-SVR中有效,nu設(shè)置v-SVC、一類(lèi)SVM和v-SVR參數(shù),p為設(shè)置e-SVR中損失函數(shù)的值,class_weightsC_SVC的權(quán)重,term_crit為SVM訓(xùn)練過(guò)程的終止條件。其中默認(rèn)值degree = 0,gamma = 1,coef0 = 0,Cvalue = 1,nu = 0,p = 0,class_weights = 0
3)訓(xùn)練SVM
調(diào)用CvSVM::train函數(shù)建立SVM模型,第一個(gè)參數(shù)為訓(xùn)練數(shù)據(jù),第二個(gè)參數(shù)為分類(lèi)結(jié)果,最后一個(gè)參數(shù)即CvSVMParams
4)用這個(gè)SVM進(jìn)行分類(lèi)
調(diào)用函數(shù)CvSVM::predict實(shí)現(xiàn)分類(lèi)
5)獲得支持向量
除了分類(lèi),也可以得到SVM的支持向量,調(diào)用函數(shù)CvSVM::get_support_vector_count獲得支持向量的個(gè)數(shù),CvSVM::get_support_vector獲得對(duì)應(yīng)的索引編號(hào)的支持向量。
實(shí)現(xiàn)代碼如下:運(yùn)行步驟
- // 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);
- }
實(shí)驗(yàn)代碼1:顏色分類(lèi)
- //利用SVM解決2維空間向量的3級(jí)分類(lèi)問(wèn)題
- #include "stdafx.h"
- #include "cv.h"
- #include "highgui.h"
- #include <ML.H>
- #include <TIME.H>
-
- #include <CTYPE.H>
-
- #include <IOSTREAM>
- using namespace std;
- int main(int argc, char **argv)
- {
- int size = 400; //圖像的長(zhǎng)度和寬度
- const int s = 1000; //試驗(yàn)點(diǎn)個(gè)數(shù)(可更改!?。?nbsp;
- int i, j, sv_num;
- IplImage *img;
- CvSVM svm = CvSVM(); //★★★
- CvSVMParams param;
- CvTermCriteria criteria;//停止迭代的標(biāo)準(zhǔn)
- CvRNG rng = cvRNG(time(NULL));
- CvPoint pts[s]; //定義1000個(gè)點(diǎn)
- float data[s*2]; //點(diǎn)的坐標(biāo)
- int res[s]; //點(diǎn)的所屬類(lèi)
- CvMat data_mat, res_mat;
- CvScalar rcolor;
- const float *support;
- // (1)圖像區(qū)域的確保和初始化
- img= cvCreateImage(cvSize(size, size), IPL_DEPTH_8U, 3);
- cvZero(img);
- //確保畫(huà)像區(qū)域,并清0(用黑色作初始化處理)。
-
- // (2)學(xué)習(xí)數(shù)據(jù)的生成
- for (i= 0; i< s; i++) {
- pts[i].x= cvRandInt(&rng) % size; //用隨機(jī)整數(shù)賦值
- pts[i].y= cvRandInt(&rng) % size;
- if (pts[i].y> 50 * cos(pts[i].x* CV_PI/ 100) + 200) {
- cvLine(img, cvPoint(pts[i].x- 2, pts[i].y- 2), cvPoint(pts[i].x+ 2, pts[i].y+ 2), CV_RGB(255, 0, 0));
- cvLine(img, cvPoint(pts[i].x+ 2, pts[i].y- 2), cvPoint(pts[i].x- 2, pts[i].y+ 2), CV_RGB(255, 0, 0));
- res[i] = 1;
- }
- else {
- if (pts[i].x> 200) {
- cvLine(img, cvPoint(pts[i].x- 2, pts[i].y- 2), cvPoint(pts[i].x+ 2, pts[i].y+ 2), CV_RGB(0, 255, 0));
- cvLine(img, cvPoint(pts[i].x+ 2, pts[i].y- 2), cvPoint(pts[i].x- 2, pts[i].y+ 2), CV_RGB(0, 255, 0));
- res[i] = 2;
- }
- else {
- cvLine(img, cvPoint(pts[i].x- 2, pts[i].y- 2), cvPoint(pts[i].x+ 2, pts[i].y+ 2), CV_RGB(0, 0, 255));
- cvLine(img, cvPoint(pts[i].x+ 2, pts[i].y- 2), cvPoint(pts[i].x- 2, pts[i].y+ 2), CV_RGB(0, 0, 255));
- res[i] = 3;
- }
- }
- }
- //生成2維隨機(jī)訓(xùn)練數(shù)據(jù),并將其值放在CvPoint數(shù)據(jù)類(lèi)型的數(shù)組pts[ ]中。
-
- // (3)學(xué)習(xí)數(shù)據(jù)的顯示
- cvNamedWindow("SVM", CV_WINDOW_AUTOSIZE);
- cvShowImage("SVM", img);
- cvWaitKey(0);
-
- // (4)學(xué)習(xí)參數(shù)的生成
- for (i= 0; i< s; i++) {
- data[i* 2] = float (pts[i].x) / size;
- data[i* 2 + 1] = float (pts[i].y) / size;
- }
- cvInitMatHeader(&data_mat, s, 2, CV_32FC1, data);
- cvInitMatHeader(&res_mat, s, 1, CV_32SC1, res);
- criteria= cvTermCriteria(CV_TERMCRIT_EPS, 1000, FLT_EPSILON);
- param= CvSVMParams (CvSVM::C_SVC, CvSVM::RBF, 10.0, 8.0, 1.0, 10.0, 0.5, 0.1, NULL, criteria);
- /*
- SVM種類(lèi):CvSVM::C_SVC
- Kernel的種類(lèi):CvSVM::RBF
- degree:10.0(此次不使用)
- gamma:8.0
- coef0:1.0(此次不使用)
- C:10.0
- nu:0.5(此次不使用)
- p:0.1(此次不使用)
- 然后對(duì)訓(xùn)練數(shù)據(jù)正規(guī)化處理,并放在CvMat型的數(shù)組里。
- */
-
-
- //☆☆☆☆☆☆☆☆☆(5)SVM學(xué)習(xí)☆☆☆☆☆☆☆☆☆☆☆☆
- svm.train(&data_mat, &res_mat, NULL, NULL, param);//☆
- //☆☆利用訓(xùn)練數(shù)據(jù)和確定的學(xué)習(xí)參數(shù),進(jìn)行SVM學(xué)習(xí)☆☆☆☆
-
- // (6)學(xué)習(xí)結(jié)果的繪圖
- for (i= 0; i< size; i++) {
- for (j= 0; j< size; j++) {
- CvMat m;
- float ret = 0.0;
- float a[] = { float (j) / size, float (i) / size };
- cvInitMatHeader(&m, 1, 2, CV_32FC1, a);
- ret= svm.predict(&m);
- switch ((int) ret) {
- case 1:
- rcolor= CV_RGB(100, 0, 0);
- break;
- case 2:
- rcolor= CV_RGB(0, 100, 0);
- break;
- case 3:
- rcolor= CV_RGB(0, 0, 100);
- break;
- }
- cvSet2D(img, i, j, rcolor);
- }
- }
- //為了顯示學(xué)習(xí)結(jié)果,通過(guò)輸入圖像區(qū)域的所有像素(特征向量)并進(jìn)行分類(lèi)。然后對(duì)輸入像素用所屬等級(jí)的顏色繪圖。
-
- // (7)訓(xùn)練數(shù)據(jù)的再繪制
- for (i= 0; i< s; i++) {
- CvScalar rcolor;
- switch (res[i]) {
- case 1:
- rcolor= CV_RGB(255, 0, 0);
- break;
- case 2:
- rcolor= CV_RGB(0, 255, 0);
- break;
- case 3:
- rcolor= CV_RGB(0, 0, 255);
- break;
- }
- cvLine(img, cvPoint(pts[i].x- 2, pts[i].y- 2), cvPoint(pts[i].x+ 2, pts[i].y+ 2), rcolor);
- cvLine(img, cvPoint(pts[i].x+ 2, pts[i].y- 2), cvPoint(pts[i].x- 2, pts[i].y+ 2), rcolor);
- }
- //將訓(xùn)練數(shù)據(jù)在結(jié)果圖像上重復(fù)的繪制出來(lái)。
-
- // (8)支持向量的繪制
- sv_num= svm.get_support_vector_count();
- for (i= 0; i< sv_num; i++) {
- support = svm.get_support_vector(i);
- cvCircle(img, cvPoint((int) (support[0] * size), (int) (support[1] * size)), 5, CV_RGB(200, 200, 200));
- }
- //用白色的圓圈對(duì)支持向量作標(biāo)記。
-
- // (9)圖像的顯示
- cvNamedWindow("SVM", CV_WINDOW_AUTOSIZE);
- cvShowImage("SVM", img);
- cvWaitKey(0);
- cvDestroyWindow("SVM");
- cvReleaseImage(&img);
- return 0;
- //顯示實(shí)際處理結(jié)果的圖像,直到某個(gè)鍵被按下為止。
- }
實(shí)驗(yàn)代碼2:用MIT人臉庫(kù)檢測(cè),效果實(shí)在不好,檢測(cè)結(jié)果全是人臉或者全都不是人臉。原因應(yīng)該是圖像檢測(cè)沒(méi)有做好應(yīng)該用HoG等特征首先檢測(cè),在進(jìn)行分類(lèi)訓(xùn)練,不特征不明顯,肯定分類(lèi)效果并不好。
- //////////////////////////////////////////////////////////////////////////
- // File Name: pjSVM.cpp
- // Author: easyfov(easyfov@gmail.com)
- // Company: Lida Optical and Electronic Co.,Ltd.
- //http://apps.hi.baidu.com/share/detail/32719017
- //////////////////////////////////////////////////////////////////////////
-
- #include <cv.h>
- #include <highgui.h>
- #include <ml.h>
-
- #include <iostream>
- #include <fstream>
- #include <string>
- #include <vector>
- using namespace std;
-
- #define WIDTH 20
- #define HEIGHT 20
-
- int main( /*int argc, char** argv*/ )
- {
- vector<string> img_path;
- vector<int> img_catg;
- int nLine = 0;
- string buf;
- ifstream svm_data( "E:/SVM_DATA.txt" );
-
- while( svm_data )
- {
- if( getline( svm_data, buf ) )
- {
- nLine ++;
- if( nLine % 2 == 0 )
- {
- img_catg.push_back( atoi( buf.c_str() ) );//atoi將字符串轉(zhuǎn)換成整型,標(biāo)志(0,1)
- }
- else
- {
- img_path.push_back( buf );//圖像路徑
- }
- }
- }
- svm_data.close();//關(guān)閉文件
-
- CvMat *data_mat, *res_mat;
- int nImgNum = nLine / 2; //讀入樣本數(shù)量
- ////樣本矩陣,nImgNum:橫坐標(biāo)是樣本數(shù)量, WIDTH * HEIGHT:樣本特征向量,即圖像大小
- data_mat = cvCreateMat( nImgNum, WIDTH * HEIGHT, CV_32FC1 );
- cvSetZero( data_mat );
- //類(lèi)型矩陣,存儲(chǔ)每個(gè)樣本的類(lèi)型標(biāo)志
- res_mat = cvCreateMat( nImgNum, 1, CV_32FC1 );
- cvSetZero( res_mat );
-
- IplImage *srcImg, *sampleImg;
- float b;
- DWORD n;
-
- for( string::size_type i = 0; i != img_path.size(); i++ )
- {
- srcImg = cvLoadImage( img_path[i].c_str(), CV_LOAD_IMAGE_GRAYSCALE );
- if( srcImg == NULL )
- {
- cout<<" can not load the image: "<<img_path[i].c_str()<<endl;
- continue;
- }
-
- cout<<" processing "<<img_path[i].c_str()<<endl;
-
- sampleImg = cvCreateImage( cvSize( WIDTH, HEIGHT ), IPL_DEPTH_8U, 1 );//樣本大?。╓IDTH, HEIGHT)
- cvResize( srcImg, sampleImg );//改變圖像大小
-
- cvSmooth( sampleImg, sampleImg ); //降噪
- //生成訓(xùn)練數(shù)據(jù)
- n = 0;
- for( int ii = 0; ii < sampleImg->height; ii++ )
- {
- for( int jj = 0; jj < sampleImg->width; jj++, n++ )
- {
- b = (float)((int)((uchar)( sampleImg->imageData + sampleImg->widthStep * ii + jj )) / 255.0 );
- cvmSet( data_mat, (int)i, n, b );
- }
- }
- cvmSet( res_mat, i, 0, img_catg[i] );
- cout<<" end processing "<<img_path[i].c_str()<<" "<<img_catg[i]<<endl;
- }
-
-
- CvSVM svm = CvSVM();
- CvSVMParams param;
- CvTermCriteria criteria;
- criteria = cvTermCriteria( CV_TERMCRIT_EPS, 1000, FLT_EPSILON );
- param = CvSVMParams( CvSVM::C_SVC, CvSVM::RBF, 10.0, 0.09, 1.0, 10.0, 0.5, 1.0, NULL, criteria );
- /*
- SVM種類(lèi):CvSVM::C_SVC
- Kernel的種類(lèi):CvSVM::RBF
- degree:10.0(此次不使用)
- gamma:8.0
- coef0:1.0(此次不使用)
- C:10.0
- nu:0.5(此次不使用)
- p:0.1(此次不使用)
- 然后對(duì)訓(xùn)練數(shù)據(jù)正規(guī)化處理,并放在CvMat型的數(shù)組里。
- */
- //☆☆☆☆☆☆☆☆☆(5)SVM學(xué)習(xí)☆☆☆☆☆☆☆☆☆☆☆☆
- svm.train( data_mat, res_mat, NULL, NULL, param );
- //☆☆利用訓(xùn)練數(shù)據(jù)和確定的學(xué)習(xí)參數(shù),進(jìn)行SVM學(xué)習(xí)☆☆☆☆
- svm.save( "SVM_DATA.xml" );
-
-
- //檢測(cè)樣本
- IplImage *tst, *tst_tmp;
- vector<string> img_tst_path;
- ifstream img_tst( "E:/SVM_TEST.txt" );
- while( img_tst )
- {
- if( getline( img_tst, buf ) )
- {
- img_tst_path.push_back( buf );
- }
- }
- img_tst.close();
-
- CvMat *tst_mat = cvCreateMat( 1, WIDTH*HEIGHT, CV_32FC1 );
- char line[512];
- ofstream predict_txt( "SVM_PREDICT.txt" );
- for( string::size_type j = 0; j != img_tst_path.size(); j++ )
- {
- tst = cvLoadImage( img_tst_path[j].c_str(), CV_LOAD_IMAGE_GRAYSCALE );
- if( tst == NULL )
- {
- cout<<" can not load the image: "<<img_tst_path[j].c_str()<<endl;
- continue;
- }
- tst_tmp = cvCreateImage( cvSize( WIDTH, HEIGHT ), IPL_DEPTH_8U, 1 );
- cvResize( tst, tst_tmp );
- cvSmooth( tst_tmp, tst_tmp );
- n = 0;
- for(int ii = 0; ii < tst_tmp->height; ii++ )
- {
- for(int jj = 0; jj < tst_tmp->width; jj++, n++ )
- {
- b = (float)(((int)((uchar)tst_tmp->imageData+tst_tmp->widthStep*ii+jj))/255.0);
- cvmSet( tst_mat, 0, n, (double)b );
- }
- }
-
- int ret = svm.predict( tst_mat );
- sprintf( line, "%s %d\r\n", img_tst_path[j].c_str(), ret );
- predict_txt<<line;
- }
- predict_txt.close();
-
- cvReleaseImage( &srcImg );
- cvReleaseImage( &sampleImg );
- cvReleaseImage( &tst );
- cvReleaseImage( &tst_tmp );
- cvReleaseMat( &data_mat );
- cvReleaseMat( &res_mat );
-
- return 0;
- }
其中
G:/program/pjSVM/face/1.png 0 G:/program/pjSVM/face/2.png 0 G:/program/pjSVM/face/3.png 0 G:/program/pjSVM/face/4.png 0 G:/program/pjSVM/face/5.png 0 G:/program/pjSVM/face/6.png 0 G:/program/pjSVM/face/7.png 0 G:/program/pjSVM/face/8.png 0 G:/program/pjSVM/face/9.png 0 G:/program/pjSVM/face/10.png 0 G:/program/pjSVM/face/11.png 0 G:/program/pjSVM/face/12.png 0 G:/program/pjSVM/face/13.png 0 G:/program/pjSVM/face/14.png 0 G:/program/pjSVM/face/15.png 1 G:/program/pjSVM/face/16.png 1 G:/program/pjSVM/face/17.png 1 G:/program/pjSVM/face/18.png 1 G:/program/pjSVM/face/19.png 1 G:/program/pjSVM/face/20.png 1 G:/program/pjSVM/face/21.png 1 G:/program/pjSVM/face/22.png 1 G:/program/pjSVM/face/23.png 1 G:/program/pjSVM/face/24.png 1 G:/program/pjSVM/face/25.png 1 G:/program/pjSVM/face/26.png 1 G:/program/pjSVM/face/27.png 1 G:/program/pjSVM/face/28.png 1 G:/program/pjSVM/face/29.png 1 G:/program/pjSVM/face/30.png
1
SVM_TEST.txt中內(nèi)容如下:
G:/program/pjSVM/try_face/5.png G:/program/pjSVM/try_face/9.png G:/program/pjSVM/try_face/11.png G:/program/pjSVM/try_face/15.png G:/program/pjSVM/try_face/2.png G:/program/pjSVM/try_face/30.png G:/program/pjSVM/try_face/17.png G:/program/pjSVM/try_face/21.png G:/program/pjSVM/try_face/24.png G:/program/pjSVM/try_face/27.png
PS:txt操作簡(jiǎn)單方式:http://blog.csdn.net/lytwell/article/details/6029503
|