OpenCV·机器学习·线性SVM

来源:互联网 发布:台湾网络信号 编辑:程序博客网 时间:2024/06/05 07:25
本文基于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 运行结果


这里写图片描述

阅读全文
0 0