OpenCV·机器学习·线性SVM

本文基于OpenCV官方文档和源码
工具:Win10+VS2015+OpenCV3.2+OpenCV官方文档
  1. SVM
    SVM:支持向量机(Support Vector Machine),多用于分类任务。
    有关支持向量机的学习可以参阅周志华老师《机器学习》一书的第6章,介绍得非常精简到位。

  2. OpenCV里面的线性SVM
    对于实践类知识的学习,我更倾向于直接看例程,然后遇到不懂的就查阅官方文档。所以在此直接上代码:

#include <opencv2/core.hpp>
#include <opencv2/imgproc.hpp>
#include <opencv2/imgcodecs.hpp>
#include <opencv2/highgui.hpp>
#include <opencv2/ml.hpp>

using namespace cv;
using namespace cv::ml;

int main()
{
    // 创建用于可视化的图像
    int width = 512, height = 512;
    Mat image = Mat::zeros(height, width, CV_8UC3);

    // 第一步,设置训练数据:标签,数据点
    int labels[4] = { 1, -1, -1, -1 }; //定义样本标签
    float trainingData[4][2] = { { 501, 10 },{ 255, 10 },{ 501, 255 },{ 10, 501 } }; //定义样本点
    Mat trainingDataMat(4, 2, CV_32FC1, trainingData); //样本点
    Mat labelsMat(4, 1, CV_32SC1, labels); //样本标签

    // 训练SVM
    // 第二步,SVM参数初始化
    Ptr<SVM> svm = SVM::create();
    svm->setType(SVM::C_SVC);     //设置类型C_SVC,允许处理不完美情况,即不是线性可分的情况下也会给个结果,即使这个结果不好
    svm->setKernel(SVM::LINEAR);  //设置核函数类型,LINEAR:线性
    //设置训练终止调剂,三个参数分别为:终止类型,最大迭代次数,精度
    svm->setTermCriteria(TermCriteria(TermCriteria::MAX_ITER, 100, 1e-6)); 

    // 第三步,SVM训练
    // train()函数包含三个参数:samples,layout,responses,只有samples是必须要设置的参数
    // 只设置第一个参数,训练会采用无监督学习算法;如果设置后两个参数,则采用有监督学习算法训练
    svm->train(trainingDataMat, ROW_SAMPLE, labelsMat);

    // 第四步,显示由SVM决策出的分类区域
    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) << j, i);
            float response = svm->predict(sampleMat); //得到预测的类别结果

            if (response == 1)
                image.at<Vec3b>(i, j) = green;
            else if (response == -1)
                image.at<Vec3b>(i, j) = 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(255, 255, 255), 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);

    // 第六步,显示支持向量
    // 支持向量:距离划分超平面最近的训练样本点
    thickness = 2;
    lineType = 8;
    Mat sv = svm->getUncompressedSupportVectors(); //得到支持向量,返回float类型的Mat
    for (int i = 0; i < sv.rows; ++i)
    {
        const float* v = sv.ptr<float>(i);
        circle(image, Point((int)v[0], (int)v[1]), 6, Scalar(128, 128, 128), thickness, lineType);
    }

    //第七步,图像保存与显示
    imwrite("result.png", image);      
    imshow("SVM Simple Example", image); 

    waitKey(0);
    return 0;
}

3 运行结果


这里写图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值