opencv SVM详解(一)(官方实例)

依据机器学习算法如何学习数据可分为3类:

  1. 有监督学习:从有标签的数据学习,得到模型参数,对测试数据正确分类;
  2. 无监督学习:没有标签,计算机自己寻找输入数据可能的模型;
  3. 强化学习(reinforcement learning):计算机与动态环境交互,学习错误反馈达到更优的目的。

依据机器学习期望结果来分类:

  1. 分类:输入被分为N个类别的一种;
  2. 回归:输出是连续值;如依据房子的大小,时间,位置来预测房子的价格;
  3. 聚类:使用无监督学习将输入聚为N类;
  4. 密度估计(density estimation):找到输入可能的分布;

以OpenCV的SVM为例:


支持向量机较其他传统机器学习算法的优点:
1、小样本,并不是说样本的绝对数量少(实际上,对任何算法来说,更多的样本几乎总是能带来更好的效果),而是说与问题的复杂度比起来,SVM算法要求的样本数是相对比较少的。SVM解决问题的时候,和样本的维数是无关的(甚至样本是上万维的都可以,这使得SVM很适合用来解决文本分类的问题,当然,有这样的能力也因为引入了核函数)。
2、结构风险最小。(对问题真实模型的逼近与问题真实解之间的误差,就叫做风险,更严格的说,误差的累积叫做风险)。
3、非线性,是指SVM擅长应付样本数据线性不可分的情况,主要通过松弛变量(也有人叫惩罚变量)和核函数技术来实现,这一部分是SVM的精髓。

SVM的精髓之一核函数:OpenCV提供了以下几种

  • 线性核函数:SVM::LINEAR,线性内核,没有高维空间映射,速度快;
  • 多项式核函数:SVM::POLY,gamma>0,coef(),degree;
  • 径向基核函数: SVM::RBF,比较好的选择,gamma>0;
  • SIGMOD核函数:这个核让人想起神经网络和深度学习。。gamma,coef();

上面核中记录了SVM使用的参数;见SVMParams();

C++: CvSVMParams::CvSVMParams(int svm_type, int kernel_type, double degree, double gamma, double coef0, double Cvalue, double nu, double p, CvMat* class_weights, CvTermCriteria term_crit)

svm_type:SVM类型:

  1. CvSVM::C_SVC : C类支撑向量分类机。 n类分组 (n≥2),容许用异常值处罚因子C进行不完全分类。
  2. CvSVM::NU_SVC : 类支撑向量分类机。n类似然不完全分类的分类器。参数为gamma代替C。
  3. CvSVM::ONE_CLASS : 单分类器,所有的练习数据提取自同一个类里,然后SVM建树了一个分界线以分别该类在特点空间中所占区域和其它类在特点空间中所占区域。
  4. CvSVM::EPS_SVR : 用于回归。练习集中的特征向量和拟合出来的超平面的间隔须要小于p。异常值处罚因子C被采取。
  5. CvSVM::NU_SVR : 回归机,gamma代替p

kernel_type:即上面所说的核函数类型;仔细看可以发现这两个参数类型都是int,所以除了填这些宏一样的名称外也可以直接填1,2,3.。。。
degree,gamma,coef0,都是特定核函数使用的参数,上面有总结;
Cvalue:SVM类型(C_SVC/ EPS_SVR/ NU_SVR)的参数C。
nu: SVM类型(NU_SVC/ ONE_CLASS/ NU_SVR)的参数 gamma;
p: SVM类型(EPS_SVR)的参数
class_weights: C_SVC中的可选权重,赋给指定的类,乘以C后变成 class_weights*C;
term_crit: SVM的迭代终止条件,可以指定的公差和最大迭代次数。
不设置时使用默认初始值初始化各参数。

SVM的训练函数有两个,训练的好坏直接影响学习结果,非常重要。

C++: bool CvSVM::train(const Mat& trainData, const Mat& responses, const Mat& varIdx=Mat(), const Mat& sampleIdx=Mat(), CvSVMParams params=CvSVMParams() )

C++: bool CvSVM::train_auto();

推荐第二个,因为能帮你优化参数啊!!!除非你自认调参能力出众可选第一个!

训练后就是预测了,SVM有以下三种形式:

C++: float CvSVM::predict(const Mat& sample, bool returnDFVal=false ) const
C++: float CvSVM::predict(const CvMat* sample, bool returnDFVal=false ) const
C++: float CvSVM::predict(const CvMat* samples, CvMat* results) const

sample:  须要预测的输入样本;samples: 须要预测的输入样本们,多个;
returnDFVal:  指定返回值类型。若值是true,则是一个2类分类问题;
results:  响应的样本输出猜测的响应;分类中返回的是标签类别号;

来看一下OPENCV文档的例子:

void TestSVM1()
{
     
    int width = 512, height = 512;
    Mat image = Mat::zeros(height, width, CV_8UC3);

    // set up training data
    float labels[4] = { 1.0, 1.0, -1.0, -1.0 };
    Mat labelsMat(4, 1, CV_32FC1, labels);

    float trainingData[4][2] = { { 501, 10 }, { 255, 10 }, { 501, 255 }, { 10, 501 } };
    Mat trainingDataMat(4, 2, CV_32FC1, trainingData);

    // set up SVM's parameters
    CvSVMParams params;
    params.svm_type = CvSVM::C_SVC;
    params.kernel_type = CvSVM::LINEAR;
    params.term_crit = cvTermCriteria(CV_TERMCRIT_ITER, 100, 1e-6);

    // train the svm
    CvSVM SVM;
    SVM.train(trainingDataMat, labelsMat, Mat(), Mat(), params);

    Vec3b green(0, 255, 0), blue(255, 0, 0);

    // show the decision region given by the SVM
    for (int i = 0; i < image.rows; ++i)
    {
        for (int j = 0; j < image.cols; ++j)
        {
            Mat sampleMat = (Mat_<float>(1, 2) << i, j);

            // predict 函数使用训练好的SVM模型对一个输入的样本进行分类
            float response = SVM.predict(sampleMat);

            if (response == 1)
            {
                // 注意这里是(j,i),不是(i,j)
                image.at<Vec3b>(j, i) = green;
            }
            else
            {
                // 同上
                image.at<Vec3b>(j, i) = blue;
            }
        }
    }

    int thickness = -1;
    int lineType = 8;

    circle(image, Point(501, 10), 5, Scalar(0, 0, 0), thickness, lineType);
    circle(image, Point(255, 10), 5, Scalar(0, 0, 0), thickness, lineType);
    circle(image, Point(501, 255), 5, Scalar(255, 255, 255), thickness, lineType);
    circle(image, Point(10, 501), 5, Scalar(255, 255, 255), thickness, lineType);

    // show support vectors
    thickness = 2;
    lineType = 8;

    // 获得当前的支持向量的个数
    int c = SVM.get_support_vector_count();

    for (int i = 0; i < c; ++i)
    {
        const float* v = SVM.get_support_vector(i);
        circle(image, Point((int)v[0], (int)v[1]), 6, Scalar(128, 128, 128), thickness, lineType);
    }

    //imwrite("result.png", image); // save the image

    imshow("SVM Simple Example", image); // show it to the user
    waitKey(0);
    return;
}

看代码的label可以知道是一个二分类问题,输入为四个点,核函数也是线性核。

运行结果:

四个点每个类才两个点总觉得不够看啊,笔者增加了点数还是二分类,分界面看上去好多了。

运行结果:

每个类6点,看上去分类更有规律了。

总结

以上是转载别人的内容,另外我自己也找了一些好的博客,在这里分享下 学习SVM(共五篇)SVM 训练行人检测器

原文链接:http://www.cnblogs.com/chenzhefan/p/7662315.html

原文作者:巴尔扎克_S

  • 5
    点赞
  • 39
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
OpenCV中的SVM(支持向量机)是一种机器学习算法,用于分类和回归问题。SVM通过将训练数据映射到高维空间,并在该空间中找到一个最优超平面来分离不同的类别。它可以在不同的核函数(如线性核、多项式核和高斯核)下工作,并且可以根据数据的特性和问题的要求进行设置。 在OpenCV中,使用SVM的步骤如下: 1. 创建一个分类器对象:使用cv::ml::SVM::create()函数创建一个SVM分类器对象。 2. 设置相关参数:通过svm->setType()设置分类器类型,svm->setKernel()设置核函数类型,并使用其他函数设置其他参数,如svm->setGamma()、svm->setC()、svm->setTermCriteria()等。 3. 获取数据集:创建训练数据集,使用cv::ml::TrainData::create()函数将数据和标签传递给训练数据对象。 4. 训练模型:使用svm->train()函数训练分类器,传入训练数据集。 5. 预测:使用svm->predict()函数对测试数据进行预测,返回预测结果。 6. 保存和加载模型:使用svm->save()函数将模型保存为xml文件,使用cv::ml::SVM::load()函数加载保存的模型。 此外,还可以使用cv::ml::SVM::trainAuto()函数来自动选择最优参数进行训练,该函数会尝试不同的参数组合,并选择效果最好的参数。 希望以上信息能够对你有所帮助。如果还有其他问题,请随时提问。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* *3* [OpenCV(一)---支持向量机 SVM](https://blog.csdn.net/qq_42995327/article/details/114462958)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 100%"] [ .reference_list ]
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值