从0基于开始使用opencv关于SVM的使用,网上查阅相关资料后,终于可以相应的实现功能,相应的代码如下。
但是需要注意的几个问题,这也是我遇到的已经解决的,类型不对会出现相应的断言。
但是没有弄明白的是支持向量为什么是(0,0),不是应该是样本中的一些值么?
#include "opencv2/opencv.hpp"
#include "opencv2/imgproc.hpp"
#include "opencv2/highgui.hpp"
#include "opencv2/ml.hpp"
//#include "ml.h"
using namespace cv;
#include
using namespace std;
int main( )
{
//Console::WriteLine(L"Hello World");
int iWidth = 512, iheight = 512;
cv::Mat matImg = cv::Mat::zeros(iheight, iWidth, CV_8UC3);//三色通道
//1.获取样本
int labels[5] = { 1.0, -1.0, -1.0, -1.0,1.0 }; //样本数据
Mat labelsMat(5, 1, CV_32SC1, labels); //样本标签
float trainingData[5][2] = { { 501, 300 },{ 255, 10 },{ 501, 255 },{ 10, 501 },{ 450,500 } }; //Mat结构特征数据
Mat trainingDataMat(5, 2, CV_32FC1, trainingData); //Mat结构标签
//2.设置SVM参数
cv::Ptr
svm->setType(cv::ml::SVM::C_SVC);//可以处理非线性分割的问题
svm->setKernel(cv::ml::SVM::LINEAR);//径向基函数
/*svm->setGamma(0.01);
svm->setC(10.0);*/
//算法终止条件
svm->setTermCriteria(cv::TermCriteria(CV_TERMCRIT_ITER, 100, 1e-6));
//3.训练支持向量
svm->train(trainingDataMat, ml::SampleTypes::ROW_SAMPLE,labelsMat);
//4.保存训练器
svm->save("mnist_svm.xml");
//5.导入训练器
//Ptr
//读取测试数据
cv::Vec3b green(0, 255, 0), blue(255, 0, 0);
for (int i = 0; i < matImg.rows; i++)
{
for (int j = 0; j < matImg.cols; j++)
{
cv::Mat sampleMat = (cv::Mat_
float fRespone = svm->predict(sampleMat);
if (fRespone == 1)
{
matImg.at
}
else if(fRespone == -1)
{
matImg.at
}
}
}
// Show the training data
int thickness = -1;
int lineType = 8;
for (int i = 0; i < trainingDataMat.rows;i++)
{
if (labels[i] == 1)
{
circle(matImg, cv::Point(trainingData[i][0], trainingData[i][1]), 5, cv::Scalar(0, 0, 0), thickness, lineType);
}
else
{
circle(matImg, cv::Point(trainingData[i][0], trainingData[i][1]), 5, cv::Scalar(255, 255, 255), thickness, lineType);
}
}
//cvShowImage("circle", &((IplImage)matImg)); // show it to the user
//cvWaitKey(0);
//显示支持向量点
thickness = 2;
lineType = 8;
cv::Mat vec = svm->getSupportVectors();
int nVarCount = svm->getVarCount();//支持向量的维数
for (int i = 0; i < vec.rows; ++i)
{
int x = (int)vec.at
int y = (int)vec.at
circle(matImg, Point(x,y), 6, Scalar(0, 0, 255), thickness, lineType);
}
cvShowImage("circle", &((IplImage)matImg)); // show it to the user
cvWaitKey(0);
return 0;
}
相关的也可以参照 http://blog.csdn.net/guoyunfei20/article/details/78105493
如果核函数用ml::SVM::LINEAR,下边Mat SupportVectorsMat = svm->getSupportVectors();将无法正常输出支持向量。这并非BUG,官方解释: