分享

opencv中svm支持向量机c++简单例子introduction

 清风明月0391 2013-12-16

最近在做一些纹理分割方面的东西,需要提取图像特征后进行训练分类。在师兄的指点下了解SVM(支持向量机)可以达到很好的效果。

在opencv(版本)自带OpenCV\samples\cpp\tutorial_code\ml\introduction_to_svm  下找到了简单的introduction_to_svm.cpp

  1. #include <opencv2/core/core.hpp>   
  2. #include <opencv2/highgui/highgui.hpp>   
  3. #include <opencv2/ml/ml.hpp>   
  4.   
  5. using namespace cv;  
  6.   
  7. int main()  
  8. {  
  9.     // Data for visual representation   
  10.     int width = 512, height = 512;  
  11.     Mat image = Mat::zeros(height, width, CV_8UC3);  
  12.   
  13.     // Set up training data   
  14.     float labels[4] = {1.0, -1.0, -1.0, -1.0};  
  15.     Mat labelsMat(4, 1, CV_32FC1, labels);  
  16.   
  17.     float trainingData[4][2] = { {501, 10}, {255, 10}, {501, 255}, {10, 501} };  
  18.     Mat trainingDataMat(4, 2, CV_32FC1, trainingData);  
  19.   
  20.     // Set up SVM's parameters   
  21.     CvSVMParams params;  
  22.     params.svm_type    = CvSVM::C_SVC;  
  23.     params.kernel_type = CvSVM::LINEAR;  
  24.     params.term_crit   = cvTermCriteria(CV_TERMCRIT_ITER, 100, 1e-6);  
  25.   
  26.     // Train the SVM   
  27.     CvSVM SVM;  
  28.     SVM.train(trainingDataMat, labelsMat, Mat(), Mat(), params);  
  29.   
  30.     Vec3b green(0,255,0), blue (255,0,0);  
  31.     // Show the decision regions given by the SVM   
  32.     for (int i = 0; i < image.rows; ++i)  
  33.         for (int j = 0; j < image.cols; ++j)  
  34.         {  
  35.             Mat sampleMat = (Mat_<float>(1,2) << i,j);  
  36.             float response = SVM.predict(sampleMat);  
  37.   
  38.             if (response == 1)  
  39.                 image.at<Vec3b>(j, i)  = green;  
  40.             else if (response == -1)  
  41.                  image.at<Vec3b>(j, i)  = blue;  
  42.         }  
  43.   
  44.     // Show the training data   
  45.     int thickness = -1;  
  46.     int lineType = 8;  
  47.     circle( image, Point(501,  10), 5, Scalar(  0,   0,   0), thickness, lineType);  
  48.     circle( image, Point(255,  10), 5, Scalar(255, 255, 255), thickness, lineType);  
  49.     circle( image, Point(501, 255), 5, Scalar(255, 255, 255), thickness, lineType);  
  50.     circle( image, Point( 10, 501), 5, Scalar(255, 255, 255), thickness, lineType);  
  51.   
  52.     // Show support vectors   
  53.     thickness = 2;  
  54.     lineType  = 8;  
  55.     int c     = SVM.get_support_vector_count();  
  56.   
  57.     for (int i = 0; i < c; ++i)  
  58.     {  
  59.         const float* v = SVM.get_support_vector(i);  
  60.         circle( image,  Point( (int) v[0], (int) v[1]),   6,  Scalar(128, 128, 128), thickness, lineType);  
  61.     }  
  62.   
  63.     imwrite("result.png", image);        // save the image   
  64.   
  65.     imshow("SVM Simple Example", image); // show it to the user   
  66.     waitKey(0);  
  67.   
  68. }  

在该段程序中,我们运行后得到结果图如下图所示:


但是如果我们将代码第10行的width值改为1024,则数组越界。

最后发现在代码的39行

  1. if (response == 1)  
  2.     image.at<Vec3b>(j, i)  = green;  
  3. else if (response == -1)  
  4.      image.at<Vec3b>(j, i)  = blue;  

中,将i,j位置改变后,

  1. if (response == 1)  
  2.     image.at<Vec3b>(i, j)  = green;  
  3. else if (response == -1)  
  4.     image.at<Vec3b>(i, j)  = blue;  


得到结果

  1. <IMG alt="" src="http://img.blog.csdn.net/20131212212856531">  

明显结果有问题,由于我们改了坐标35行的Mat sampleMat = (Mat_<float>(1,2) << i,j);
顺序也要调换一下,改为Mat sampleMat = (Mat_<float>(1,2) << j,i);结果图就很正常了,如下图


分析该问题的产生原因,主要是image.at<Vec3b>(j, i)这段代码是先行后列,顺序反了。归根到底opencv中的svm以空间为特征的话,一定记得顺序的对应关系,否则会出现很奇怪的结果。

最终修改后代码如下所示:

  1. #include <opencv2/core/core.hpp>   
  2. #include <opencv2/highgui/highgui.hpp>   
  3. #include <opencv2/ml/ml.hpp>   
  4.   
  5. using namespace cv;  
  6.   
  7. int main()  
  8. {  
  9.     // Data for visual representation   
  10.     int width = 1024, height = 512;  
  11.     Mat image = Mat::zeros(height, width, CV_8UC3);  
  12.   
  13.     // Set up training data   
  14.     float labels[4] = {1.0, -1.0, -1.0, -1.0};  
  15.     Mat labelsMat(4, 1, CV_32FC1, labels);  
  16.   
  17.     float trainingData[4][2] = { {501, 10}, {255, 10}, {501, 255}, {10, 501} };  
  18.     Mat trainingDataMat(4, 2, CV_32FC1, trainingData);  
  19.   
  20.     // Set up SVM's parameters   
  21.     CvSVMParams params;  
  22.     params.svm_type    = CvSVM::C_SVC;  
  23.     params.kernel_type = CvSVM::LINEAR;  
  24.     params.term_crit   = cvTermCriteria(CV_TERMCRIT_ITER, 100, 1e-6);  
  25.   
  26.     // Train the SVM   
  27.     CvSVM SVM;  
  28.     SVM.train(trainingDataMat, labelsMat, Mat(), Mat(), params);  
  29.   
  30.     Vec3b green(0,255,0), blue (255,0,0);  
  31.     // Show the decision regions given by the SVM   
  32.     for (int i = 0; i < image.rows; ++i)  
  33.         for (int j = 0; j < image.cols; ++j)  
  34.         {  
  35.             Mat sampleMat = (Mat_<float>(1,2) << j,i);  
  36.             float response = SVM.predict(sampleMat);  
  37.   
  38.             if (response == 1)  
  39.                 image.at<Vec3b>(i, j)  = green;  
  40.             else if (response == -1)  
  41.                 image.at<Vec3b>(i, j)  = blue;  
  42.         }  
  43.   
  44.         // Show the training data   
  45.         int thickness = -1;  
  46.         int lineType = 8;  
  47.         circle( image, Point(501,  10), 5, Scalar(  0,   0,   0), thickness, lineType);  
  48.         circle( image, Point(255,  10), 5, Scalar(255, 255, 255), thickness, lineType);  
  49.         circle( image, Point(501, 255), 5, Scalar(255, 255, 255), thickness, lineType);  
  50.         circle( image, Point( 10, 501), 5, Scalar(255, 255, 255), thickness, lineType);  
  51.   
  52.         // Show support vectors   
  53.         thickness = 2;  
  54.         lineType  = 8;  
  55.         int c     = SVM.get_support_vector_count();  
  56.   
  57.         for (int i = 0; i < c; ++i)  
  58.         {  
  59.             const float* v = SVM.get_support_vector(i);  
  60.             circle( image,  Point( (int) v[0], (int) v[1]),   6,  Scalar(128, 128, 128), thickness, lineType);  
  61.         }  
  62.   
  63.         imwrite("result.png", image);        // save the image   
  64.   
  65.         imshow("SVM Simple Example", image); // show it to the user   
  66.         waitKey(0);  
  67.   
  68. }  


    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多