#include <iostream>
#include<opencv2/opencv.hpp>
#include<ctype.h>
#define NTRAINING_SAMPLES 100 // Number of training samples per class
#define FRAC_LINEAR_SEP 0.9f // Fraction of samples which compose the linear separable part
using namespace cv;
using namespace std;
using namespace cv::ml;
int main(int argc, char* argv[])
{
int size = 400; // height and widht of image
const int s = 1000; // number of data
int i, j, sv_num;
Mat img;
srand(time(NULL)); // 设置随机数种子
RNG rng(12345);
Point pts[s]; // 定义1000个点
float data[s * 2]; // 点的坐标
int res[s]; // 点的类别
const float* support;
// 图像区域的初始化
img = Mat::zeros(Size(size, size), CV_8UC3);
// 学习数据的生成
for (i = 0; i < s; ++i)
{
pts[i].x = rand() % size;
pts[i].y = rand() % size;
if (pts[i].y > 50 * cos(pts[i].x * CV_PI / 100) + 200)
{
line(img,Point(pts[i].x - 2, pts[i].y - 2), Point(pts[i].x + 2, pts[i].y + 2), Scalar(255, 0, 0));
line(img, Point(pts[i].x + 2, pts[i].y - 2), Point(pts[i].x - 2, pts[i].y + 2), Scalar(255, 0, 0));
res[i] = 1;
}
else
{
if (pts[i].x > 200)
{
line(img, Point(pts[i].x - 2, pts[i].y - 2), Point(pts[i].x + 2, pts[i].y + 2), Scalar(0, 255, 0));
line(img, Point(pts[i].x + 2, pts[i].y - 2), Point(pts[i].x - 2, pts[i].y + 2), Scalar(0, 255, 0));
res[i] = 2;
}
else
{
line(img, Point(pts[i].x - 2, pts[i].y - 2), Point(pts[i].x + 2, pts[i].y + 2), Scalar(0, 0, 255));
line(img, Point(pts[i].x + 2, pts[i].y - 2), Point(pts[i].x - 2, pts[i].y + 2), Scalar(0, 0, 255));
res[i] = 3;
}
}
}
// 学习数据的现实
namedWindow("SVM训练样本空间及分类", WINDOW_AUTOSIZE);
imshow("SVM训练样本空间及分类", img);
//waitKey(0);
// 学习参数的生成
for (i = 0; i < s; ++i)
{
data[i * 2] = float(pts[i].x) / size;
data[i * 2 + 1] = float(pts[i].y) / size;
}
//创建svm
Ptr<SVM> svm = SVM::create();
Mat data_mat(1000,2,CV_32FC1,data);
Mat res_mat(s,1,CV_32SC1,res);
svm->setTermCriteria(TermCriteria(TermCriteria::EPS,1000, FLT_EPSILON));
svm->setType(SVM::C_SVC);
svm->setKernel(SVM::RBF);
svm->setDegree(10.0);//高斯核的参数设置
svm->setGamma(8.0);
svm->setCoef0(1.0);
svm->setC(10.0);
svm->setNu(0.5);
svm->setP(0.1);
Ptr<TrainData> traind = TrainData::create(data_mat,ROW_SAMPLE,res_mat);
svm->train(traind);
// 学习结果绘图
Vec3b red(0, 0, 255), green(0, 255, 0), blue(255, 0, 0);
for (i = 0; i < size; i++)
{
for (j = 0; j < size; j++)
{
float ret = 0.0;
float a[] = { float(j) / size,float(i) / size };
Mat m(1,2,CV_32FC1,a);
ret = svm->predict(m);
switch ((int)ret)
{
case 1:
img.at<Vec3b>(i, j) = red;
break;
case 2:
img.at<Vec3b>(i, j) = green;
break;
case 3:
img.at<Vec3b>(i, j) = blue;
break;
}
}
}
// 为了显示学习结果,通过对输入图像区域的所有像素(特征向量)进行分类,然后对输入的像素用所属颜色等级的颜色绘图
for (i = 0; i < s; ++i)
{
Scalar rcolor;
switch (res[i])
{
case 1:
rcolor = Scalar(100, 0, 0);
break;
case 2:
rcolor = Scalar(0, 100, 0);
break;
case 3:
rcolor = Scalar(0, 0, 100);
break;
}
line(img, Point(pts[i].x - 2, pts[i].y - 2), Point(pts[i].x + 2, pts[i].y + 2), rcolor);
line(img, Point(pts[i].x + 2, pts[i].y - 2), Point(pts[i].x - 2, pts[i].y + 2), rcolor);
}
// 支持向量的绘制
imshow("SVM分类结果及支持向量", img);
waitKey(0);
return 0;
}
机器学习:SVM分割数据点(线性不可分多分类)
最新推荐文章于 2023-04-21 23:15:37 发布