首页 > 代码库 > OpenCV Tutorials —— Introduction to Support Vector Machines

OpenCV Tutorials —— Introduction to Support Vector Machines

支持向量机 ~~

 

How is the optimal hyperplane computed?

Let’s introduce the notation used to define formally a hyperplane:

f(x) = \beta_{0} + \beta^{T} x,

where \beta is known as the weight vector and \beta_{0} as the bias.

 

The optimal hyperplane can be represented in an infinite number of different ways by scaling of \beta and \beta_{0}. As a matter of convention, among all the possible representations of the hyperplane, the one chosen is

|\beta_{0} + \beta^{T} x| = 1

where x symbolizes the training examples closest to the hyperplane. In general, the training examples that are closest to the hyperplane are called support vectors. This representation is known as the canonical hyperplane.

Now, we use the result of geometry that gives the distance between a point x and a hyperplane (\beta, \beta_{0}):

\mathrm{distance} = \frac{|\beta_{0} + \beta^{T} x|}{||\beta||}.

In particular, for the canonical hyperplane, the numerator is equal to one and the distance to the support vectors is

\mathrm{distance}_{\text{ support vectors}} = \frac{|\beta_{0} + \beta^{T} x|}{||\beta||} = \frac{1}{||\beta||}.

Recall that the margin introduced in the previous section, here denoted as M, is twice the distance to the closest examples:

M = \frac{2}{||\beta||}

Finally, the problem of maximizing M is equivalent to the problem of minimizing a function L(\beta) subject to some constraints. The constraints model the requirement for the hyperplane to classify correctly all the training examples x_{i}. Formally,

\min_{\beta, \beta_{0}} L(\beta) = \frac{1}{2}||\beta||^{2} \text{ subject to } y_{i}(\beta^{T} x_{i} + \beta_{0}) \geq 1 \text{ } \forall i,

where y_{i} represents each of the labels of the training examples.

This is a problem of Lagrangian optimization that can be solved using Lagrange multipliers to obtain the weight vector \beta and the bias \beta_{0} of the optimal hyperplane.

 

float labels[4] = {1.0, -1.0, -1.0, -1.0};float trainingData[4][2] = {{501, 10}, {255, 10}, {501, 255}, {10, 501}};Mat trainingDataMat(3, 2, CV_32FC1, trainingData);Mat labelsMat      (3, 1, CV_32FC1, labels);

The function CvSVM::train that will be used afterwards requires the training data to be stored as Mat objects of floats.  数组转Mat

 

 

CvSVMParams params;params.svm_type    = CvSVM::C_SVC;params.kernel_type = CvSVM::LINEAR;params.term_crit   = cvTermCriteria(CV_TERMCRIT_ITER, 100, 1e-6);

 

The methodCvSVM::get_support_vector_count outputs the total number of support vectors used in the problem and with the method CvSVM::get_support_vector we obtain each of the support vectors using an index.

 

 

Code

#include "stdafx.h"#include <opencv2/core/core.hpp>#include <opencv2/highgui/highgui.hpp>#include <opencv2/ml/ml.hpp>using namespace cv;int main(){	// Data for visual representation	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 regions 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) << j,i);	// 每个像素点都进行predict			float response = SVM.predict(sampleMat);			if (response == 1)				image.at<Vec3b>(i,j)  = green;			else if (response == -1)				image.at<Vec3b>(i,j)  = blue;		}		// Show the training data		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);		// 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);}

OpenCV Tutorials —— Introduction to Support Vector Machines