⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 机器学习中文参考手册 - opencv china.htm

📁 When I use opencv, I use this very useful paper to begin the study. This is all I searched from the
💻 HTM
📖 第 1 页 / 共 5 页
字号:
    cvSet( &trainClasses1, cvScalar(1) );

    cvGetRows( trainClasses, &trainClasses2, train_sample_count/2, train_sample_count );
    cvSet( &trainClasses2, cvScalar(2) );

    // learn classifier
    CvKNearest knn( trainData, trainClasses, 0, false, K );
    CvMat* nearests = cvCreateMat( 1, K, CV_32FC1);

    for( i = 0; i < img->height; i++ )
    {
        for( j = 0; j < img->width; j++ )
        {
            sample.data.fl[0] = (float)j;
            sample.data.fl[1] = (float)i;

            // estimates the response and get the neighbors' labels
            response = knn.find_nearest(&sample,K,0,0,nearests,0);

            // compute the number of neighbors representing the majority
            for( k = 0, accuracy = 0; k < K; k++ )
            {
                if( nearests->data.fl[k] == response)
                    accuracy++;
            }
            // highlight the pixel depending on the accuracy (or confidence)
            cvSet2D( img, i, j, response == 1 ?
                (accuracy > 5 ? CV_RGB(180,0,0) : CV_RGB(180,120,0)) :
                (accuracy > 5 ? CV_RGB(0,180,0) : CV_RGB(120,120,0)) );
        }
    }

    // display the original training samples
    for( i = 0; i < train_sample_count/2; i++ )
    {
        CvPoint pt;
        pt.x = cvRound(trainData1.data.fl[i*2]);
        pt.y = cvRound(trainData1.data.fl[i*2+1]);
        cvCircle( img, pt, 2, CV_RGB(255,0,0), CV_FILLED );
        pt.x = cvRound(trainData2.data.fl[i*2]);
        pt.y = cvRound(trainData2.data.fl[i*2+1]);
        cvCircle( img, pt, 2, CV_RGB(0,255,0), CV_FILLED );
    }

    cvNamedWindow( "classifier result", 1 );
    cvShowImage( "classifier result", img );
    cvWaitKey(0);

    cvReleaseMat( &trainClasses );
    cvReleaseMat( &trainData );
    return 0;
}
</PRE>
<DIV class=editsection style="FLOAT: right; MARGIN-LEFT: 5px">[<A 
title=机器学习中文参考手册 
href="http://www.opencv.org.cn/index.php?title=%E6%9C%BA%E5%99%A8%E5%AD%A6%E4%B9%A0%E4%B8%AD%E6%96%87%E5%8F%82%E8%80%83%E6%89%8B%E5%86%8C&amp;action=edit&amp;section=22">编辑</A>]</DIV><A 
name=.E6.94.AF.E6.92.91.E5.90.91.E9.87.8F.E6.9C.BA.E9.83.A8.E5.88.86></A>
<H1>支撑向量机部分 </H1>
<P>支撑向量机(SVM),起初由vapnik提出时,是作为寻求最优(在一定程度上)二分类器的一种技术。後来它又被拓展到回归和聚类应用。SVM是一种基于核函数的方法,它通过某些核函数把特征向量映射到高维空间,然後建立一个线性判别函数(或者说是一个高维空间中的能够区分训练数据的最优超平面,参考异或那个经典例子)。假如SVM没有明确定义核函数,高维空间中任意两点距离就需要定义。 
</P>
<P>解是最优的在某种意义上是两类中距离分割面最近的特征向量和分割面的距离最大化。离分割面最近的特征向量被称为”支撑向量”,意即其它向量不影响分割面(决策函数)。 
</P>
<P>有很多关于SVM的参考文献,这是两篇较好的入门文献。 </P>
<P>【Burges98】 C. Burges. "A tutorial on support vector machines for pattern 
recognition", Knowledge Discovery and Data Mining 2(2), 1998. (available online 
at <A class="external autonumber" 
title=http://citeseer.ist.psu.edu/burges98tutorial.html 
href="http://citeseer.ist.psu.edu/burges98tutorial.html" rel=nofollow>[1]</A>). 
</P>
<P>LIBSVM - A Library for Support Vector Machines. By Chih-Chung Chang and 
Chih-Jen Lin (<A class="external autonumber" 
title=http://www.csie.ntu.edu.tw/~cjlin/libsvm/ 
href="http://www.csie.ntu.edu.tw/~cjlin/libsvm/" rel=nofollow>[2]</A>) </P>
<DIV class=editsection style="FLOAT: right; MARGIN-LEFT: 5px">[<A 
title=机器学习中文参考手册 
href="http://www.opencv.org.cn/index.php?title=%E6%9C%BA%E5%99%A8%E5%AD%A6%E4%B9%A0%E4%B8%AD%E6%96%87%E5%8F%82%E8%80%83%E6%89%8B%E5%86%8C&amp;action=edit&amp;section=23">编辑</A>]</DIV><A 
name=CvSVM></A>
<H2>CvSVM</H2>
<P>支撑矢量机 </P><PRE>class CvSVM&nbsp;: public CvStatModel //继承自基类CvStatModel
{
public:
    // SVM type
    enum { C_SVC=100, NU_SVC=101, ONE_CLASS=102, EPS_SVR=103, NU_SVR=104 };//SVC是SVM分类器,SVR是SVM回归

    // SVM kernel type
    enum { LINEAR=0, POLY=1, RBF=2, SIGMOID=3 }; //提供四种核函数,分别是线性,多项式,径向基,sigmoid型函数。

    CvSVM();
    virtual ~CvSVM();

    CvSVM( const CvMat* _train_data, const CvMat* _responses,
           const CvMat* _var_idx=0, const CvMat* _sample_idx=0,
           CvSVMParams _params=CvSVMParams() );

    virtual bool train( const CvMat* _train_data, const CvMat* _responses,
                        const CvMat* _var_idx=0, const CvMat* _sample_idx=0,
                        CvSVMParams _params=CvSVMParams() );

    virtual float predict( const CvMat* _sample ) const;
    virtual int get_support_vector_count() const;
    virtual const float* get_support_vector(int i) const;
    virtual void clear();

    virtual void save( const char* filename, const char* name=0 );
    virtual void load( const char* filename, const char* name=0 );

    virtual void write( CvFileStorage* storage, const char* name );
    virtual void read( CvFileStorage* storage, CvFileNode* node );
    int get_var_count() const { return var_idx&nbsp;? var_idx-&gt;cols&nbsp;: var_all; }

protected:
    ...
};
</PRE>
<DIV class=editsection style="FLOAT: right; MARGIN-LEFT: 5px">[<A 
title=机器学习中文参考手册 
href="http://www.opencv.org.cn/index.php?title=%E6%9C%BA%E5%99%A8%E5%AD%A6%E4%B9%A0%E4%B8%AD%E6%96%87%E5%8F%82%E8%80%83%E6%89%8B%E5%86%8C&amp;action=edit&amp;section=24">编辑</A>]</DIV><A 
name=CvSVMParams></A>
<H2>CvSVMParams</H2>
<P>SVM训练参数struct </P><PRE>struct CvSVMParams
{
    CvSVMParams();
    CvSVMParams( int _svm_type, int _kernel_type,
                 double _degree, double _gamma, double _coef0,
                 double _C, double _nu, double _p,
                 CvMat* _class_weights, CvTermCriteria _term_crit );

    int         svm_type;
    int         kernel_type;
    double      degree; // for poly
    double      gamma;  // for poly/rbf/sigmoid
    double      coef0;  // for poly/sigmoid

    double      C;  // for CV_SVM_C_SVC, CV_SVM_EPS_SVR and CV_SVM_NU_SVR
    double      nu; // for CV_SVM_NU_SVC, CV_SVM_ONE_CLASS, and CV_SVM_NU_SVR
    double      p; // for CV_SVM_EPS_SVR
    CvMat*      class_weights; // for CV_SVM_C_SVC
    CvTermCriteria term_crit; // termination criteria
};
</PRE>
<P>svm_type,SVM的类型: </P>
<DL>
  <DD>CvSVM::C_SVC - n(n&gt;=2)分类器,允许用异常值惩罚因子C进行不完全分类。 
  <DD>CvSVM::NU_SVC - n类似然不完全分类的分类器。参数nu取代了c,其值在区间【0,1】中,nu越大,决策边界越平滑。 
  <DD>CvSVM::ONE_CLASS - 
  单分类器,所有的训练数据提取自同一个类里,然後SVM建立了一个分界线以分割该类在特征空间中所占区域和其它类在特征空间中所占区域。 
  <DD>CvSVM::EPS_SVR - 回归。 训练集中的特征向量和拟合出来的超平面的距离需要小于p。异常值惩罚因子C被采用。 
  <DD>CvSVM::NU_SVR - 回归;nu 代替了p </DD></DL>
<P>kernel_type//核类型: </P>
<DL>
  <DD>CvSVM::LINEAR - 没有任何向映射至高维空间,线性区分(或回归)在原始特征空间中被完成,这是最快的选择。 d(x,y) = x•y == 
  (x,y) 
  <DD>CvSVM::POLY - 多项式核: d(x,y) = (gamma*(x•y)+coef0)degree 
  <DD>CvSVM::RBF - 径向基,对于大多数情况都是一个较好的选择:d(x,y) = exp(-gamma*|x-y|2) 
  <DD>CvSVM::SIGMOID - sigmoid函数被用作核函数: d(x,y) = tanh(gamma*(x•y)+coef0) 
</DD></DL>
<P>degree, gamma, coef0:都是核函数的参数,具体的参见上面的核函数的方程。 </P>
<P>C, nu, p:在一般的SVM优化求解时的参数。 </P>
<P>class_weights: Optional weights, assigned to particular classes. They are 
multiplied by C and thus affect the mis-classification penalty for different 
classes. The larger weight, the larger penalty on mis-classification of data 
from the certain class. </P>
<P>term_crit: Termination procedure for iterative SVM training procedure (which 
solves a partial case of constrained quadratic optimization problem) The 
structure needs to be initialized and passed to the training method of CvSVM 
</P>
<DIV class=editsection style="FLOAT: right; MARGIN-LEFT: 5px">[<A 
title=机器学习中文参考手册 
href="http://www.opencv.org.cn/index.php?title=%E6%9C%BA%E5%99%A8%E5%AD%A6%E4%B9%A0%E4%B8%AD%E6%96%87%E5%8F%82%E8%80%83%E6%89%8B%E5%86%8C&amp;action=edit&amp;section=25">编辑</A>]</DIV><A 
name=CvSVM::train></A>
<H2>CvSVM::train</H2>
<P>训练SVM </P><PRE>bool CvSVM::train( const CvMat* _train_data, const CvMat* _responses,
                   const CvMat* _var_idx=0, const CvMat* _sample_idx=0,
                   CvSVMParams _params=CvSVMParams() );
</PRE>
<P>The method trains SVM model. It follows the conventions of generic train 
"method" with the following limitations: only CV_ROW_SAMPLE data layout is 
supported, the input variables are all ordered, the output variables can be 
either categorical (_params.svm_type=CvSVM::C_SVC or 
_params.svm_type=CvSVM::NU_SVC) or ordered (_params.svm_type=CvSVM::EPS_SVR or 
_params.svm_type=CvSVM::NU_SVR) or not required at all 
(_params.svm_type=CvSVM::ONE_CLASS), missing measurements are not supported. 
</P>
<P>所有的参数都被集成在CvSVMParams这个结构中。 </P>
<P><BR></P>
<DIV class=editsection style="FLOAT: right; MARGIN-LEFT: 5px">[<A 
title=机器学习中文参考手册 
href="http://www.opencv.org.cn/index.php?title=%E6%9C%BA%E5%99%A8%E5%AD%A6%E4%B9%A0%E4%B8%AD%E6%96%87%E5%8F%82%E8%80%83%E6%89%8B%E5%86%8C&amp;action=edit&amp;section=26">编辑</A>]</DIV><A 
name=CvSVM::get_support_vector.2A></A>
<H2>CvSVM::get_support_vector*</H2>
<P>得到支撑矢量和特殊矢量的数 </P><PRE>int CvSVM::get_support_vector_count() const;
const float* CvSVM::get_support_vector(int i) const;
</PRE>
<P>这个方法可以被用来得到支撑矢量的集合。 </P>
<DIV class=editsection style="FLOAT: right; MARGIN-LEFT: 5px">[<A 
title=机器学习中文参考手册 
href="http://www.opencv.org.cn/index.php?title=%E6%9C%BA%E5%99%A8%E5%AD%A6%E4%B9%A0%E4%B8%AD%E6%96%87%E5%8F%82%E8%80%83%E6%89%8B%E5%86%8C&amp;action=edit&amp;section=27">编辑</A>]</DIV><A 
name=.E8.A1.A5.E5.85.85:.E5.9C.A8WindowsXP.2BOpenCVRC1.E5.B9.B3.E5.8F.B0.E4.B8.8B.E6.95.B4.E5.90.88OpenCV.E4.B8.8ElibSVM></A>
<H2>补充:在WindowsXP+OpenCVRC1平台下整合OpenCV与libSVM </H2>
<P>虽然从RC1版开始opencv开始增设ML类,提供对常见的分类器和回归算法的支持。但是尚存在一些问题,比如说例子少(官方许诺说很快会提供一批新例子,见CVS版)。单说SVM这种算法,它自己提供了一套比较完备的函数,但是并不见得优于老牌的libsvm(它也应该参考过libsvm,至于是否效率优于libsvm,我并没有作过测试,官方也没有什么说法,但是libsvm持续开源更新,是公认的现存的开源SVM库中最易上手,性能最好的库)。所以在你的程序里整合opencv和libSVM还是一种比较好的解决方案。在VC中整合有些小地方需要注意,这篇文档主要是提供把图象作为SVM输入时程序遇到的这些小问题的解决方案。希望大家遇到问题时,多去读libSVM的源码,它本身也是开源的,C代码写得也很优秀,数据结构定义得也比较好。 
</P>
<P>首先是SVM的训练,这部分我并没有整合到VC里,直接使用它提供的python程序,虽然网格搜索这种简易搜索也可以自己写,但是识别时只需要训练生成的SVMmodel文件即可,所以可以和主程序分离开。至于python在windows下的使用,还是要设置一下的,首先要在系统环境变量path里把python的路径设进去,libsvm画训练等高线图还需要gnuplot的支持,打开python源程序(grid.py),把gnuplot_exe设置成你机器里的安装路径,这样才能正确的运行程序。然後就是改步长和搜索范围,官方建议是先用大步长搜索,搜到最优值後再用小步长在小范围内搜索(我觉得这有可能会陷入局部最优,不过近似出的结果还可以接受)。我用的python版本是2.4,gnuplot4.0。 
</P>

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -