小男孩‘自慰网亚洲一区二区,亚洲一级在线播放毛片,亚洲中文字幕av每天更新,黄aⅴ永久免费无码,91成人午夜在线精品,色网站免费在线观看,亚洲欧洲wwwww在线观看

分享

學(xué)習(xí)OpenCV——SVM

 年華似水匆匆 2013-12-11

學(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)行步驟

  1. // step 1:   
  2. float labels[4] = {1.0, -1.0, -1.0, -1.0};  
  3. Mat labelsMat(3, 1, CV_32FC1, labels);  
  4.   
  5. float trainingData[4][2] = { {501, 10}, {255, 10}, {501, 255}, {10, 501} };  
  6. Mat trainingDataMat(3, 2, CV_32FC1, trainingData);  
  7.   
  8. // step 2:   
  9. CvSVMParams params;  
  10. params.svm_type = CvSVM::C_SVC;  
  11. params.kernel_type = CvSVM::LINEAR;  
  12. params.term_crit = cvTermCriteria(CV_TERMCRIT_ITER, 100, 1e-6);  
  13.   
  14. // step 3:   
  15. CvSVM SVM;  
  16. SVM.train(trainingDataMat, labelsMat, Mat(), Mat(), params);  
  17.   
  18. // step 4:   
  19. Vec3b green(0, 255, 0), blue(255, 0, 0);  
  20. for (int i=0; i<image.rows; i++)  
  21. {  
  22.     for (int j=0; j<image.cols; j++)  
  23.     {  
  24.         Mat sampleMat = (Mat_<float>(1,2) << i,j);  
  25.         float response = SVM.predict(sampleMat);  
  26.   
  27.         if (fabs(response-1.0) < 0.0001)  
  28.         {  
  29.             image.at<Vec3b>(j, i) = green;  
  30.         }  
  31.         else if (fabs(response+1.0) < 0.001)  
  32.         {  
  33.             image.at<Vec3b>(j, i) = blue;  
  34.         }  
  35.     }  
  36. }  
  37.   
  38. // step 5:   
  39. int c = SVM.get_support_vector_count();  
  40.   
  41. for (int i=0; i<c; i++)  
  42. {  
  43.     const float* v = SVM.get_support_vector(i);  
  44. }  

 

實(shí)驗(yàn)代碼1:顏色分類(lèi)

  1. //利用SVM解決2維空間向量的3級(jí)分類(lèi)問(wèn)題       
  2. #include "stdafx.h"       
  3. #include "cv.h"       
  4. #include "highgui.h"              
  5. #include <ML.H>       
  6. #include <TIME.H>       
  7.      
  8. #include <CTYPE.H>       
  9.     
  10. #include <IOSTREAM>       
  11. using namespace std;     
  12. int main(int argc, char **argv)     
  13. {     
  14.         int size = 400;         //圖像的長(zhǎng)度和寬度       
  15.         const int s = 1000;          //試驗(yàn)點(diǎn)個(gè)數(shù)(可更改?。。?nbsp;      
  16.         int i, j, sv_num;     
  17.         IplImage *img;     
  18.         CvSVM svm = CvSVM();    //★★★       
  19.         CvSVMParams param;     
  20.         CvTermCriteria criteria;//停止迭代的標(biāo)準(zhǔn)       
  21.         CvRNG rng = cvRNG(time(NULL));     
  22.         CvPoint pts[s];         //定義1000個(gè)點(diǎn)       
  23.         float data[s*2];        //點(diǎn)的坐標(biāo)       
  24.         int res[s];             //點(diǎn)的所屬類(lèi)       
  25.         CvMat data_mat, res_mat;     
  26.         CvScalar rcolor;     
  27.         const float *support;     
  28.         // (1)圖像區(qū)域的確保和初始化       
  29.         img= cvCreateImage(cvSize(size, size), IPL_DEPTH_8U, 3);     
  30.         cvZero(img);     
  31.         //確保畫(huà)像區(qū)域,并清0(用黑色作初始化處理)。       
  32.          
  33.         // (2)學(xué)習(xí)數(shù)據(jù)的生成       
  34.         for (i= 0; i< s; i++) {     
  35.             pts[i].x= cvRandInt(&rng) % size;   //用隨機(jī)整數(shù)賦值       
  36.             pts[i].y= cvRandInt(&rng) % size;     
  37.             if (pts[i].y> 50 * cos(pts[i].x* CV_PI/ 100) + 200) {     
  38.                 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));     
  39.                 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));     
  40.                 res[i] = 1;     
  41.             }     
  42.             else {     
  43.                 if (pts[i].x> 200) {     
  44.                     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));     
  45.                     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));     
  46.                     res[i] = 2;     
  47.                 }     
  48.                 else {     
  49.                     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));     
  50.                     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));     
  51.                     res[i] = 3;     
  52.                 }     
  53.             }     
  54.         }     
  55.         //生成2維隨機(jī)訓(xùn)練數(shù)據(jù),并將其值放在CvPoint數(shù)據(jù)類(lèi)型的數(shù)組pts[ ]中。       
  56.          
  57.         // (3)學(xué)習(xí)數(shù)據(jù)的顯示       
  58.         cvNamedWindow("SVM", CV_WINDOW_AUTOSIZE);     
  59.         cvShowImage("SVM", img);     
  60.         cvWaitKey(0);     
  61.          
  62.         // (4)學(xué)習(xí)參數(shù)的生成       
  63.         for (i= 0; i< s; i++) {     
  64.             data[i* 2] = float (pts[i].x) / size;     
  65.             data[i* 2 + 1] = float (pts[i].y) / size;     
  66.         }     
  67.         cvInitMatHeader(&data_mat, s, 2, CV_32FC1, data);     
  68.         cvInitMatHeader(&res_mat, s, 1, CV_32SC1, res);     
  69.         criteria= cvTermCriteria(CV_TERMCRIT_EPS, 1000, FLT_EPSILON);     
  70.         param= CvSVMParams (CvSVM::C_SVC, CvSVM::RBF, 10.0, 8.0, 1.0, 10.0, 0.5, 0.1, NULL, criteria);     
  71.         /*   
  72.             SVM種類(lèi):CvSVM::C_SVC   
  73.             Kernel的種類(lèi):CvSVM::RBF   
  74.             degree:10.0(此次不使用)   
  75.             gamma:8.0   
  76.             coef0:1.0(此次不使用)   
  77.             C:10.0   
  78.             nu:0.5(此次不使用)   
  79.             p:0.1(此次不使用)   
  80.             然后對(duì)訓(xùn)練數(shù)據(jù)正規(guī)化處理,并放在CvMat型的數(shù)組里。   
  81.                                                                 */     
  82.          
  83.          
  84.         //☆☆☆☆☆☆☆☆☆(5)SVM學(xué)習(xí)☆☆☆☆☆☆☆☆☆☆☆☆       
  85.         svm.train(&data_mat, &res_mat, NULL, NULL, param);//☆       
  86.         //☆☆利用訓(xùn)練數(shù)據(jù)和確定的學(xué)習(xí)參數(shù),進(jìn)行SVM學(xué)習(xí)☆☆☆☆           
  87.          
  88.         // (6)學(xué)習(xí)結(jié)果的繪圖       
  89.         for (i= 0; i< size; i++) {     
  90.             for (j= 0; j< size; j++) {     
  91.                 CvMat m;     
  92.                 float ret = 0.0;     
  93.                 float a[] = { float (j) / size, float (i) / size };     
  94.                 cvInitMatHeader(&m, 1, 2, CV_32FC1, a);     
  95.                 ret= svm.predict(&m);     
  96.                 switch ((int) ret) {     
  97.                     case 1:     
  98.                         rcolor= CV_RGB(100, 0, 0);     
  99.                         break;     
  100.                     case 2:     
  101.                         rcolor= CV_RGB(0, 100, 0);     
  102.                         break;     
  103.                     case 3:     
  104.                         rcolor= CV_RGB(0, 0, 100);     
  105.                         break;     
  106.                 }     
  107.                 cvSet2D(img, i, j, rcolor);     
  108.             }     
  109.         }     
  110.         //為了顯示學(xué)習(xí)結(jié)果,通過(guò)輸入圖像區(qū)域的所有像素(特征向量)并進(jìn)行分類(lèi)。然后對(duì)輸入像素用所屬等級(jí)的顏色繪圖。       
  111.          
  112.         // (7)訓(xùn)練數(shù)據(jù)的再繪制       
  113.         for (i= 0; i< s; i++) {     
  114.             CvScalar rcolor;     
  115.             switch (res[i]) {     
  116.                 case 1:     
  117.                     rcolor= CV_RGB(255, 0, 0);     
  118.                     break;     
  119.                 case 2:     
  120.                     rcolor= CV_RGB(0, 255, 0);     
  121.                     break;     
  122.                 case 3:     
  123.                     rcolor= CV_RGB(0, 0, 255);     
  124.                     break;     
  125.             }     
  126.             cvLine(img, cvPoint(pts[i].x- 2, pts[i].y- 2), cvPoint(pts[i].x+ 2, pts[i].y+ 2), rcolor);     
  127.             cvLine(img, cvPoint(pts[i].x+ 2, pts[i].y- 2), cvPoint(pts[i].x- 2, pts[i].y+ 2), rcolor);     
  128.         }     
  129.         //將訓(xùn)練數(shù)據(jù)在結(jié)果圖像上重復(fù)的繪制出來(lái)。       
  130.          
  131.         // (8)支持向量的繪制       
  132.         sv_num= svm.get_support_vector_count();     
  133.         for (i= 0; i< sv_num; i++) {     
  134.             support = svm.get_support_vector(i);     
  135.             cvCircle(img, cvPoint((int) (support[0] * size), (int) (support[1] * size)), 5, CV_RGB(200, 200, 200));     
  136.         }     
  137.         //用白色的圓圈對(duì)支持向量作標(biāo)記。       
  138.          
  139.         // (9)圖像的顯示        
  140.         cvNamedWindow("SVM", CV_WINDOW_AUTOSIZE);     
  141.         cvShowImage("SVM", img);     
  142.         cvWaitKey(0);     
  143.         cvDestroyWindow("SVM");     
  144.         cvReleaseImage(&img);     
  145.         return 0;     
  146.         //顯示實(shí)際處理結(jié)果的圖像,直到某個(gè)鍵被按下為止。       
  147.     }    


實(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)效果并不好。

  1. //////////////////////////////////////////////////////////////////////////   
  2. // File Name: pjSVM.cpp   
  3. // Author:   easyfov(easyfov@gmail.com)   
  4. // Company: Lida Optical and Electronic Co.,Ltd.   
  5. //http://apps.hi.baidu.com/share/detail/32719017   
  6. //////////////////////////////////////////////////////////////////////////   
  7.   
  8. #include <cv.h>   
  9. #include <highgui.h>   
  10. #include <ml.h>   
  11.   
  12. #include <iostream>   
  13. #include <fstream>   
  14. #include <string>   
  15. #include <vector>   
  16. using namespace std;  
  17.   
  18. #define WIDTH 20   
  19. #define HEIGHT 20   
  20.   
  21. int main( /*int argc, char** argv*/ )  
  22. {  
  23.     vector<string> img_path;  
  24.     vector<int> img_catg;  
  25.     int nLine = 0;  
  26.     string buf;  
  27.     ifstream svm_data( "E:/SVM_DATA.txt" );  
  28.   
  29.     while( svm_data )  
  30.     {  
  31.         if( getline( svm_data, buf ) )  
  32.         {  
  33.             nLine ++;  
  34.             if( nLine % 2 == 0 )  
  35.             {  
  36.                  img_catg.push_back( atoi( buf.c_str() ) );//atoi將字符串轉(zhuǎn)換成整型,標(biāo)志(0,1)   
  37.             }  
  38.             else  
  39.             {  
  40.                 img_path.push_back( buf );//圖像路徑   
  41.             }  
  42.         }  
  43.     }  
  44.     svm_data.close();//關(guān)閉文件   
  45.   
  46.     CvMat *data_mat, *res_mat;  
  47.     int nImgNum = nLine / 2;            //讀入樣本數(shù)量   
  48.     ////樣本矩陣,nImgNum:橫坐標(biāo)是樣本數(shù)量, WIDTH * HEIGHT:樣本特征向量,即圖像大小   
  49.     data_mat = cvCreateMat( nImgNum, WIDTH * HEIGHT, CV_32FC1 );  
  50.     cvSetZero( data_mat );  
  51.     //類(lèi)型矩陣,存儲(chǔ)每個(gè)樣本的類(lèi)型標(biāo)志   
  52.     res_mat = cvCreateMat( nImgNum, 1, CV_32FC1 );  
  53.     cvSetZero( res_mat );  
  54.   
  55.     IplImage *srcImg, *sampleImg;  
  56.     float b;  
  57.     DWORD n;  
  58.   
  59.     for( string::size_type i = 0; i != img_path.size(); i++ )  
  60.     {  
  61.        srcImg = cvLoadImage( img_path[i].c_str(), CV_LOAD_IMAGE_GRAYSCALE );  
  62.        if( srcImg == NULL )  
  63.        {  
  64.             cout<<" can not load the image: "<<img_path[i].c_str()<<endl;  
  65.             continue;  
  66.        }  
  67.   
  68.        cout<<" processing "<<img_path[i].c_str()<<endl;  
  69.   
  70.        sampleImg = cvCreateImage( cvSize( WIDTH, HEIGHT ), IPL_DEPTH_8U, 1 );//樣本大小(WIDTH, HEIGHT)   
  71.        cvResize( srcImg, sampleImg );//改變圖像大小   
  72.   
  73.        cvSmooth( sampleImg, sampleImg );    //降噪   
  74.        //生成訓(xùn)練數(shù)據(jù)   
  75.        n = 0;  
  76.         forint ii = 0; ii < sampleImg->height; ii++ )  
  77.         {  
  78.             forint jj = 0; jj < sampleImg->width; jj++, n++ )  
  79.             {  
  80.                  b = (float)((int)((uchar)( sampleImg->imageData + sampleImg->widthStep * ii + jj )) / 255.0 );  
  81.                  cvmSet( data_mat, (int)i, n, b );  
  82.             }  
  83.         }  
  84.         cvmSet( res_mat, i, 0, img_catg[i] );  
  85.         cout<<" end processing "<<img_path[i].c_str()<<" "<<img_catg[i]<<endl;  
  86.     }  
  87.   
  88.   
  89.     CvSVM svm = CvSVM();  
  90.     CvSVMParams param;  
  91.     CvTermCriteria criteria;  
  92.     criteria = cvTermCriteria( CV_TERMCRIT_EPS, 1000, FLT_EPSILON );  
  93.     param = CvSVMParams( CvSVM::C_SVC, CvSVM::RBF, 10.0, 0.09, 1.0, 10.0, 0.5, 1.0, NULL, criteria );  
  94.      /*   
  95.             SVM種類(lèi):CvSVM::C_SVC   
  96.             Kernel的種類(lèi):CvSVM::RBF   
  97.             degree:10.0(此次不使用)   
  98.             gamma:8.0   
  99.             coef0:1.0(此次不使用)   
  100.             C:10.0   
  101.             nu:0.5(此次不使用)   
  102.             p:0.1(此次不使用)   
  103.             然后對(duì)訓(xùn)練數(shù)據(jù)正規(guī)化處理,并放在CvMat型的數(shù)組里。   
  104.                                                                 */     
  105.     //☆☆☆☆☆☆☆☆☆(5)SVM學(xué)習(xí)☆☆☆☆☆☆☆☆☆☆☆☆       
  106.     svm.train( data_mat, res_mat, NULL, NULL, param );  
  107.     //☆☆利用訓(xùn)練數(shù)據(jù)和確定的學(xué)習(xí)參數(shù),進(jìn)行SVM學(xué)習(xí)☆☆☆☆   
  108.     svm.save( "SVM_DATA.xml" );  
  109.   
  110.   
  111.     //檢測(cè)樣本   
  112.     IplImage *tst, *tst_tmp;  
  113.     vector<string> img_tst_path;  
  114.     ifstream img_tst( "E:/SVM_TEST.txt" );  
  115.     while( img_tst )  
  116.     {  
  117.         if( getline( img_tst, buf ) )  
  118.         {  
  119.             img_tst_path.push_back( buf );  
  120.         }  
  121.     }  
  122.     img_tst.close();  
  123.   
  124.     CvMat *tst_mat = cvCreateMat( 1, WIDTH*HEIGHT, CV_32FC1 );  
  125.     char line[512];  
  126.     ofstream predict_txt( "SVM_PREDICT.txt" );  
  127.     for( string::size_type j = 0; j != img_tst_path.size(); j++ )  
  128.     {  
  129.         tst = cvLoadImage( img_tst_path[j].c_str(), CV_LOAD_IMAGE_GRAYSCALE );  
  130.         if( tst == NULL )  
  131.         {  
  132.              cout<<" can not load the image: "<<img_tst_path[j].c_str()<<endl;  
  133.                continue;  
  134.    }  
  135.    tst_tmp = cvCreateImage( cvSize( WIDTH, HEIGHT ), IPL_DEPTH_8U, 1 );  
  136.    cvResize( tst, tst_tmp );  
  137.    cvSmooth( tst_tmp, tst_tmp );  
  138.    n = 0;  
  139.    for(int ii = 0; ii < tst_tmp->height; ii++ )  
  140.    {  
  141.      for(int jj = 0; jj < tst_tmp->width; jj++, n++ )  
  142.      {  
  143.          b = (float)(((int)((uchar)tst_tmp->imageData+tst_tmp->widthStep*ii+jj))/255.0);  
  144.          cvmSet( tst_mat, 0, n, (double)b );  
  145.      }  
  146.    }  
  147.   
  148.    int ret = svm.predict( tst_mat );  
  149.    sprintf( line, "%s %d\r\n", img_tst_path[j].c_str(), ret );  
  150.    predict_txt<<line;  
  151. }  
  152. predict_txt.close();  
  153.   
  154. cvReleaseImage( &srcImg );  
  155. cvReleaseImage( &sampleImg );  
  156. cvReleaseImage( &tst );  
  157. cvReleaseImage( &tst_tmp );  
  158. cvReleaseMat( &data_mat );  
  159. cvReleaseMat( &res_mat );  
  160.   
  161. return 0;  
  162. }  


其中

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)行步驟

  1. // step 1:   
  2. float labels[4] = {1.0, -1.0, -1.0, -1.0};  
  3. Mat labelsMat(3, 1, CV_32FC1, labels);  
  4.   
  5. float trainingData[4][2] = { {501, 10}, {255, 10}, {501, 255}, {10, 501} };  
  6. Mat trainingDataMat(3, 2, CV_32FC1, trainingData);  
  7.   
  8. // step 2:   
  9. CvSVMParams params;  
  10. params.svm_type = CvSVM::C_SVC;  
  11. params.kernel_type = CvSVM::LINEAR;  
  12. params.term_crit = cvTermCriteria(CV_TERMCRIT_ITER, 100, 1e-6);  
  13.   
  14. // step 3:   
  15. CvSVM SVM;  
  16. SVM.train(trainingDataMat, labelsMat, Mat(), Mat(), params);  
  17.   
  18. // step 4:   
  19. Vec3b green(0, 255, 0), blue(255, 0, 0);  
  20. for (int i=0; i<image.rows; i++)  
  21. {  
  22.     for (int j=0; j<image.cols; j++)  
  23.     {  
  24.         Mat sampleMat = (Mat_<float>(1,2) << i,j);  
  25.         float response = SVM.predict(sampleMat);  
  26.   
  27.         if (fabs(response-1.0) < 0.0001)  
  28.         {  
  29.             image.at<Vec3b>(j, i) = green;  
  30.         }  
  31.         else if (fabs(response+1.0) < 0.001)  
  32.         {  
  33.             image.at<Vec3b>(j, i) = blue;  
  34.         }  
  35.     }  
  36. }  
  37.   
  38. // step 5:   
  39. int c = SVM.get_support_vector_count();  
  40.   
  41. for (int i=0; i<c; i++)  
  42. {  
  43.     const float* v = SVM.get_support_vector(i);  
  44. }  

 

實(shí)驗(yàn)代碼1:顏色分類(lèi)

  1. //利用SVM解決2維空間向量的3級(jí)分類(lèi)問(wèn)題       
  2. #include "stdafx.h"       
  3. #include "cv.h"       
  4. #include "highgui.h"              
  5. #include <ML.H>       
  6. #include <TIME.H>       
  7.      
  8. #include <CTYPE.H>       
  9.     
  10. #include <IOSTREAM>       
  11. using namespace std;     
  12. int main(int argc, char **argv)     
  13. {     
  14.         int size = 400;         //圖像的長(zhǎng)度和寬度       
  15.         const int s = 1000;          //試驗(yàn)點(diǎn)個(gè)數(shù)(可更改!?。?nbsp;      
  16.         int i, j, sv_num;     
  17.         IplImage *img;     
  18.         CvSVM svm = CvSVM();    //★★★       
  19.         CvSVMParams param;     
  20.         CvTermCriteria criteria;//停止迭代的標(biāo)準(zhǔn)       
  21.         CvRNG rng = cvRNG(time(NULL));     
  22.         CvPoint pts[s];         //定義1000個(gè)點(diǎn)       
  23.         float data[s*2];        //點(diǎn)的坐標(biāo)       
  24.         int res[s];             //點(diǎn)的所屬類(lèi)       
  25.         CvMat data_mat, res_mat;     
  26.         CvScalar rcolor;     
  27.         const float *support;     
  28.         // (1)圖像區(qū)域的確保和初始化       
  29.         img= cvCreateImage(cvSize(size, size), IPL_DEPTH_8U, 3);     
  30.         cvZero(img);     
  31.         //確保畫(huà)像區(qū)域,并清0(用黑色作初始化處理)。       
  32.          
  33.         // (2)學(xué)習(xí)數(shù)據(jù)的生成       
  34.         for (i= 0; i< s; i++) {     
  35.             pts[i].x= cvRandInt(&rng) % size;   //用隨機(jī)整數(shù)賦值       
  36.             pts[i].y= cvRandInt(&rng) % size;     
  37.             if (pts[i].y> 50 * cos(pts[i].x* CV_PI/ 100) + 200) {     
  38.                 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));     
  39.                 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));     
  40.                 res[i] = 1;     
  41.             }     
  42.             else {     
  43.                 if (pts[i].x> 200) {     
  44.                     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));     
  45.                     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));     
  46.                     res[i] = 2;     
  47.                 }     
  48.                 else {     
  49.                     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));     
  50.                     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));     
  51.                     res[i] = 3;     
  52.                 }     
  53.             }     
  54.         }     
  55.         //生成2維隨機(jī)訓(xùn)練數(shù)據(jù),并將其值放在CvPoint數(shù)據(jù)類(lèi)型的數(shù)組pts[ ]中。       
  56.          
  57.         // (3)學(xué)習(xí)數(shù)據(jù)的顯示       
  58.         cvNamedWindow("SVM", CV_WINDOW_AUTOSIZE);     
  59.         cvShowImage("SVM", img);     
  60.         cvWaitKey(0);     
  61.          
  62.         // (4)學(xué)習(xí)參數(shù)的生成       
  63.         for (i= 0; i< s; i++) {     
  64.             data[i* 2] = float (pts[i].x) / size;     
  65.             data[i* 2 + 1] = float (pts[i].y) / size;     
  66.         }     
  67.         cvInitMatHeader(&data_mat, s, 2, CV_32FC1, data);     
  68.         cvInitMatHeader(&res_mat, s, 1, CV_32SC1, res);     
  69.         criteria= cvTermCriteria(CV_TERMCRIT_EPS, 1000, FLT_EPSILON);     
  70.         param= CvSVMParams (CvSVM::C_SVC, CvSVM::RBF, 10.0, 8.0, 1.0, 10.0, 0.5, 0.1, NULL, criteria);     
  71.         /*   
  72.             SVM種類(lèi):CvSVM::C_SVC   
  73.             Kernel的種類(lèi):CvSVM::RBF   
  74.             degree:10.0(此次不使用)   
  75.             gamma:8.0   
  76.             coef0:1.0(此次不使用)   
  77.             C:10.0   
  78.             nu:0.5(此次不使用)   
  79.             p:0.1(此次不使用)   
  80.             然后對(duì)訓(xùn)練數(shù)據(jù)正規(guī)化處理,并放在CvMat型的數(shù)組里。   
  81.                                                                 */     
  82.          
  83.          
  84.         //☆☆☆☆☆☆☆☆☆(5)SVM學(xué)習(xí)☆☆☆☆☆☆☆☆☆☆☆☆       
  85.         svm.train(&data_mat, &res_mat, NULL, NULL, param);//☆       
  86.         //☆☆利用訓(xùn)練數(shù)據(jù)和確定的學(xué)習(xí)參數(shù),進(jìn)行SVM學(xué)習(xí)☆☆☆☆           
  87.          
  88.         // (6)學(xué)習(xí)結(jié)果的繪圖       
  89.         for (i= 0; i< size; i++) {     
  90.             for (j= 0; j< size; j++) {     
  91.                 CvMat m;     
  92.                 float ret = 0.0;     
  93.                 float a[] = { float (j) / size, float (i) / size };     
  94.                 cvInitMatHeader(&m, 1, 2, CV_32FC1, a);     
  95.                 ret= svm.predict(&m);     
  96.                 switch ((int) ret) {     
  97.                     case 1:     
  98.                         rcolor= CV_RGB(100, 0, 0);     
  99.                         break;     
  100.                     case 2:     
  101.                         rcolor= CV_RGB(0, 100, 0);     
  102.                         break;     
  103.                     case 3:     
  104.                         rcolor= CV_RGB(0, 0, 100);     
  105.                         break;     
  106.                 }     
  107.                 cvSet2D(img, i, j, rcolor);     
  108.             }     
  109.         }     
  110.         //為了顯示學(xué)習(xí)結(jié)果,通過(guò)輸入圖像區(qū)域的所有像素(特征向量)并進(jìn)行分類(lèi)。然后對(duì)輸入像素用所屬等級(jí)的顏色繪圖。       
  111.          
  112.         // (7)訓(xùn)練數(shù)據(jù)的再繪制       
  113.         for (i= 0; i< s; i++) {     
  114.             CvScalar rcolor;     
  115.             switch (res[i]) {     
  116.                 case 1:     
  117.                     rcolor= CV_RGB(255, 0, 0);     
  118.                     break;     
  119.                 case 2:     
  120.                     rcolor= CV_RGB(0, 255, 0);     
  121.                     break;     
  122.                 case 3:     
  123.                     rcolor= CV_RGB(0, 0, 255);     
  124.                     break;     
  125.             }     
  126.             cvLine(img, cvPoint(pts[i].x- 2, pts[i].y- 2), cvPoint(pts[i].x+ 2, pts[i].y+ 2), rcolor);     
  127.             cvLine(img, cvPoint(pts[i].x+ 2, pts[i].y- 2), cvPoint(pts[i].x- 2, pts[i].y+ 2), rcolor);     
  128.         }     
  129.         //將訓(xùn)練數(shù)據(jù)在結(jié)果圖像上重復(fù)的繪制出來(lái)。       
  130.          
  131.         // (8)支持向量的繪制       
  132.         sv_num= svm.get_support_vector_count();     
  133.         for (i= 0; i< sv_num; i++) {     
  134.             support = svm.get_support_vector(i);     
  135.             cvCircle(img, cvPoint((int) (support[0] * size), (int) (support[1] * size)), 5, CV_RGB(200, 200, 200));     
  136.         }     
  137.         //用白色的圓圈對(duì)支持向量作標(biāo)記。       
  138.          
  139.         // (9)圖像的顯示        
  140.         cvNamedWindow("SVM", CV_WINDOW_AUTOSIZE);     
  141.         cvShowImage("SVM", img);     
  142.         cvWaitKey(0);     
  143.         cvDestroyWindow("SVM");     
  144.         cvReleaseImage(&img);     
  145.         return 0;     
  146.         //顯示實(shí)際處理結(jié)果的圖像,直到某個(gè)鍵被按下為止。       
  147.     }    


實(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)效果并不好。

  1. //////////////////////////////////////////////////////////////////////////   
  2. // File Name: pjSVM.cpp   
  3. // Author:   easyfov(easyfov@gmail.com)   
  4. // Company: Lida Optical and Electronic Co.,Ltd.   
  5. //http://apps.hi.baidu.com/share/detail/32719017   
  6. //////////////////////////////////////////////////////////////////////////   
  7.   
  8. #include <cv.h>   
  9. #include <highgui.h>   
  10. #include <ml.h>   
  11.   
  12. #include <iostream>   
  13. #include <fstream>   
  14. #include <string>   
  15. #include <vector>   
  16. using namespace std;  
  17.   
  18. #define WIDTH 20   
  19. #define HEIGHT 20   
  20.   
  21. int main( /*int argc, char** argv*/ )  
  22. {  
  23.     vector<string> img_path;  
  24.     vector<int> img_catg;  
  25.     int nLine = 0;  
  26.     string buf;  
  27.     ifstream svm_data( "E:/SVM_DATA.txt" );  
  28.   
  29.     while( svm_data )  
  30.     {  
  31.         if( getline( svm_data, buf ) )  
  32.         {  
  33.             nLine ++;  
  34.             if( nLine % 2 == 0 )  
  35.             {  
  36.                  img_catg.push_back( atoi( buf.c_str() ) );//atoi將字符串轉(zhuǎn)換成整型,標(biāo)志(0,1)   
  37.             }  
  38.             else  
  39.             {  
  40.                 img_path.push_back( buf );//圖像路徑   
  41.             }  
  42.         }  
  43.     }  
  44.     svm_data.close();//關(guān)閉文件   
  45.   
  46.     CvMat *data_mat, *res_mat;  
  47.     int nImgNum = nLine / 2;            //讀入樣本數(shù)量   
  48.     ////樣本矩陣,nImgNum:橫坐標(biāo)是樣本數(shù)量, WIDTH * HEIGHT:樣本特征向量,即圖像大小   
  49.     data_mat = cvCreateMat( nImgNum, WIDTH * HEIGHT, CV_32FC1 );  
  50.     cvSetZero( data_mat );  
  51.     //類(lèi)型矩陣,存儲(chǔ)每個(gè)樣本的類(lèi)型標(biāo)志   
  52.     res_mat = cvCreateMat( nImgNum, 1, CV_32FC1 );  
  53.     cvSetZero( res_mat );  
  54.   
  55.     IplImage *srcImg, *sampleImg;  
  56.     float b;  
  57.     DWORD n;  
  58.   
  59.     for( string::size_type i = 0; i != img_path.size(); i++ )  
  60.     {  
  61.        srcImg = cvLoadImage( img_path[i].c_str(), CV_LOAD_IMAGE_GRAYSCALE );  
  62.        if( srcImg == NULL )  
  63.        {  
  64.             cout<<" can not load the image: "<<img_path[i].c_str()<<endl;  
  65.             continue;  
  66.        }  
  67.   
  68.        cout<<" processing "<<img_path[i].c_str()<<endl;  
  69.   
  70.        sampleImg = cvCreateImage( cvSize( WIDTH, HEIGHT ), IPL_DEPTH_8U, 1 );//樣本大?。╓IDTH, HEIGHT)   
  71.        cvResize( srcImg, sampleImg );//改變圖像大小   
  72.   
  73.        cvSmooth( sampleImg, sampleImg );    //降噪   
  74.        //生成訓(xùn)練數(shù)據(jù)   
  75.        n = 0;  
  76.         forint ii = 0; ii < sampleImg->height; ii++ )  
  77.         {  
  78.             forint jj = 0; jj < sampleImg->width; jj++, n++ )  
  79.             {  
  80.                  b = (float)((int)((uchar)( sampleImg->imageData + sampleImg->widthStep * ii + jj )) / 255.0 );  
  81.                  cvmSet( data_mat, (int)i, n, b );  
  82.             }  
  83.         }  
  84.         cvmSet( res_mat, i, 0, img_catg[i] );  
  85.         cout<<" end processing "<<img_path[i].c_str()<<" "<<img_catg[i]<<endl;  
  86.     }  
  87.   
  88.   
  89.     CvSVM svm = CvSVM();  
  90.     CvSVMParams param;  
  91.     CvTermCriteria criteria;  
  92.     criteria = cvTermCriteria( CV_TERMCRIT_EPS, 1000, FLT_EPSILON );  
  93.     param = CvSVMParams( CvSVM::C_SVC, CvSVM::RBF, 10.0, 0.09, 1.0, 10.0, 0.5, 1.0, NULL, criteria );  
  94.      /*   
  95.             SVM種類(lèi):CvSVM::C_SVC   
  96.             Kernel的種類(lèi):CvSVM::RBF   
  97.             degree:10.0(此次不使用)   
  98.             gamma:8.0   
  99.             coef0:1.0(此次不使用)   
  100.             C:10.0   
  101.             nu:0.5(此次不使用)   
  102.             p:0.1(此次不使用)   
  103.             然后對(duì)訓(xùn)練數(shù)據(jù)正規(guī)化處理,并放在CvMat型的數(shù)組里。   
  104.                                                                 */     
  105.     //☆☆☆☆☆☆☆☆☆(5)SVM學(xué)習(xí)☆☆☆☆☆☆☆☆☆☆☆☆       
  106.     svm.train( data_mat, res_mat, NULL, NULL, param );  
  107.     //☆☆利用訓(xùn)練數(shù)據(jù)和確定的學(xué)習(xí)參數(shù),進(jìn)行SVM學(xué)習(xí)☆☆☆☆   
  108.     svm.save( "SVM_DATA.xml" );  
  109.   
  110.   
  111.     //檢測(cè)樣本   
  112.     IplImage *tst, *tst_tmp;  
  113.     vector<string> img_tst_path;  
  114.     ifstream img_tst( "E:/SVM_TEST.txt" );  
  115.     while( img_tst )  
  116.     {  
  117.         if( getline( img_tst, buf ) )  
  118.         {  
  119.             img_tst_path.push_back( buf );  
  120.         }  
  121.     }  
  122.     img_tst.close();  
  123.   
  124.     CvMat *tst_mat = cvCreateMat( 1, WIDTH*HEIGHT, CV_32FC1 );  
  125.     char line[512];  
  126.     ofstream predict_txt( "SVM_PREDICT.txt" );  
  127.     for( string::size_type j = 0; j != img_tst_path.size(); j++ )  
  128.     {  
  129.         tst = cvLoadImage( img_tst_path[j].c_str(), CV_LOAD_IMAGE_GRAYSCALE );  
  130.         if( tst == NULL )  
  131.         {  
  132.              cout<<" can not load the image: "<<img_tst_path[j].c_str()<<endl;  
  133.                continue;  
  134.    }  
  135.    tst_tmp = cvCreateImage( cvSize( WIDTH, HEIGHT ), IPL_DEPTH_8U, 1 );  
  136.    cvResize( tst, tst_tmp );  
  137.    cvSmooth( tst_tmp, tst_tmp );  
  138.    n = 0;  
  139.    for(int ii = 0; ii < tst_tmp->height; ii++ )  
  140.    {  
  141.      for(int jj = 0; jj < tst_tmp->width; jj++, n++ )  
  142.      {  
  143.          b = (float)(((int)((uchar)tst_tmp->imageData+tst_tmp->widthStep*ii+jj))/255.0);  
  144.          cvmSet( tst_mat, 0, n, (double)b );  
  145.      }  
  146.    }  
  147.   
  148.    int ret = svm.predict( tst_mat );  
  149.    sprintf( line, "%s %d\r\n", img_tst_path[j].c_str(), ret );  
  150.    predict_txt<<line;  
  151. }  
  152. predict_txt.close();  
  153.   
  154. cvReleaseImage( &srcImg );  
  155. cvReleaseImage( &sampleImg );  
  156. cvReleaseImage( &tst );  
  157. cvReleaseImage( &tst_tmp );  
  158. cvReleaseMat( &data_mat );  
  159. cvReleaseMat( &res_mat );  
  160.   
  161. return 0;  
  162. }  


其中

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

 

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購(gòu)買(mǎi)等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶 評(píng)論公約

    類(lèi)似文章 更多