±à¼ÍƼö: |
±¾ÎĽ²½âѵÁ·Êý¾Ý¼¯£¬SVM²ÎÊýÉ趨£¬º¯Êý×÷ÓãºÅжÏsampleµÄÀà±ðµÈµÈÏ£Íû¶ÔÄúÓÐËù°ïÖú¡£
±¾ÎÄÀ´×ÔÓÚÖªºõ£¬ÓÉ»ðÁú¹ûÈí¼þDelores±à¼¡¢ÍƼö¡£ |
|
OpenCVÖм¯³ÉÁ˶àÖÖ»úÆ÷ѧϰËã·¨¹©ÎÒÃÇ·½±ãʹÓã¬Èç¹ûÎÒÃÇҪѵÁ·Êý¾Ý½øÐзÖÀ࣬²»ÓÃ×Ô¼ºÐ´·ÖÀàÆ÷£¬Ö»ÐèÒªµ÷ÓÃÏàÓ¦µÄ¿âºÍÀ༴¿ÉÇáËÉʵÏÖ¡£±¾ÎÄÖØµã²»ÔÚÓÚ½éÉÜ»úÆ÷ѧϰÔÀí¼°ÊýÑ§ÍÆµ¼£¬×ÅÖØ½éÉÜOpenCVÖеĻúÆ÷ѧϰÏà¹Øº¯Êý£¬²¢ÇÒÓÃÊ®·Ö¼òµ¥µÄѵÁ·Êý¾Ý×÷ΪÀý×ÓʵÏÖ·ÖÀà¡£
¶ÔÓÚOpenCVµÄ»úÆ÷ѧϰ·ÖÀàÆ÷£¬´ó¶à»»ÌÀ²»»»Ò©£¬¹¹Ôì·½·¨ºÍʵÏÖ·½·¨ºÜÀàËÆ£¬»ù±¾×ñÑÔʼÊý¾Ý¡ªÑµÁ··ÖÀàÆ÷¡ª½øÐзÖÀàµÄ²½Ö裬ijЩËã·¨¿ÉÄÜÓÐÌØÊâµÄ³õʼ»¯²ÎÊý£¬ÐèÒª¶îÍâÉèÖÃ
ÔÚʵÏÖÈκηÖÀàÆ÷֮ǰ£¬¶¼ÐèҪѵÁ·Êý¾Ý¡£²å¾äÌâÍâ»°£¬ÑµÁ·Êý¾ÝµÄºÃ»µÊÇÒ»¸ö·ÖÀàÆ÷³É¹¦Óë·ñµÄ¾ö¶¨ÐÔÌõ¼þ£¬Êý¾ÝѡȡÓÀÔ¶Áè¼ÝÓÚ·ÖÀàÆ÷Ë㷨ѡȡ֮ÉÏ£¬Èç¹ûѵÁ·Êý¾ÝѡȡµÃµ±£¬ÎÞÂÛʹÓÃÈκÎËã·¨¶¼»áµÃµ½²»´íµÄЧ¹û£¬·´Ö®Èç¹ûѵÁ·Êý¾Ýѡȡ²»µ±£¬·ÖÀàËã·¨ÊÇÎÞ·¨ÃÖ²¹µÄ¡£ÔÚ´ËÎÒÃÇʹÓüòµ¥µÄ¶þάÊý¾Ý×÷ΪѵÁ·Êý¾Ý£¬Æä±êºÅ·Ö±ðΪ1ºÍ-1£¬ÎÒÃÇÓÃͼÏñÀ´Ö±¹ÛµÄ±íʾ£º
//É趨800*800µÄ¶þÎ¬×ø±êÆ½ÃæÇøÓò
int width = 800, height = 800;
Mat I = Mat::zeros(height, width, CV_8UC3);
//ѵÁ·Êý¾Ý¼¯£¬Ç°10¸ö±ê¼ÇΪ1£¬ºó10¸ö±ê¼ÇΪ-1
float trainingData[20][2] =
{ { 100, 100 }, { 200, 100 }, { 400, 100 },
{ 200, 200 }, { 500, 200 },
{ 100, 300 }, { 300, 300 }, { 400, 300 }, {
100, 400 }, { 200, 500 },
{ 600, 600 }, { 700, 300 }, { 700, 300 }, {
400, 500 }, { 600, 500 },
{ 200, 700 }, { 300, 600 }, { 500, 600 }, {
600, 300 }, { 400, 700 } };
//ѵÁ·Êý¾Ý¼¯´æÈë¾ØÕó
Mat trainingDataMat(20, 2, CV_32FC1, trainingData);
//ѵÁ·Êý¾Ý±ê¼Ç£¬Ç°10¸ö±ê¼ÇΪ1£¬ºó10¸ö±ê¼ÇΪ-1
float labels[20] =
{ 1.0, 1.0, 1.0, 1.0, 1.0,
1.0, 1.0, 1.0, 1.0, 1.0,
-1.0, -1.0, -1.0, -1.0, -1.0,
-1.0, -1.0, -1.0, -1.0, -1.0 };
//ѵÁ·Êý¾Ý±ê¼Ç´æÈë¾ØÕó
Mat labelsMat(20, 1, CV_32FC1, labels);
//½«ÑµÁ·Êý¾ÝÓò»Í¬ÑÕÉ«»³ö£º1ΪÂÌÉ«£¬-1ΪÀ¶É«
for (int i = 0; i < 20; i++)
{
if (labels[i] == 1.0)
circle(I, Point(trainingData[i][0], trainingData[i][1]),
2, Scalar(255, 0, 0), 2);
else
circle(I, Point(trainingData[i][0], trainingData[i][1]),
2, Scalar(0, 255, 0), 2);
}
imshow("dataset", I); |
×¢ÒâѵÁ·Êý¾Ý¼¯¾ØÕóÀàÐÍÒ»¶¨ÊÇCV_32FC1ÐÍ£¬³¤¿í·Ö±ðΪÊý¾Ý¸öÊýºÍά¶È£¨20¸öѵÁ·Êý¾Ý£¬2ά£©£»ÑµÁ·Êý¾Ý±ê¼Ç¾ØÕóÊÇһάÏòÁ¿£¬Ò²½¨ÒéʹÓÃCV_32FC1ÐÍ£¬»¹¿ÉÓÃCV_32SC1ÐÍ£¬³¤¶ÈΪÊý¾Ý¸öÊý£¬ÒªºÍѵÁ·Êý¾ÝÒ»Ò»¶ÔÓ¦£¨ÈçÀý×ÓÖÐǰ10¸öÊý¾Ý±ê¼ÇΪ1£¬ºó10¸öÊý¾Ý±ê¼ÇΪ-1£©
½ÓÏÂÀ´ÊÇSVM²ÎÊýÉ趨£¬½¨ÒéÉ趨·½·¨Êdzõʼ»¯Ò»¸ö¿ÕÀ࣬ÐèҪʲô²ÎÊýµ¥¶ÀÉ趨£¬¾ßÌåÈçÏ£º
CvSVMParams params;
params.svm_type = CvSVM::C_SVC;
params.kernel_type = CvSVM::LINEAR;
params.term_crit = cvTermCriteria (CV_TERMCRIT_ITER,
100, FLT_EPSILON); |
ÆäÖУ¬CvSVMParams¿ÉÉèÖõIJÎÊýÓУº£¨¾ßÌå·ÖÀàÉæ¼°SVMÊýѧÔÀí£¬²»½øÐÐÕ¹¿ª£©
int svm_type£ºÓÃÀ´É趨SVMµÄÀàÐÍ£¬·ÖΪC_SVC=100, NU_SVC=101, ONE_CLASS=102, EPS_SVR=103, NU_SVR=104Õâ5ÖÖ£¬Í¨³£Ê¹ÓÃC_SVC=100×÷Ϊһ°ãµÄSVM·ÖÀàÆ÷
int kernel_type£ºÓÃÀ´É趨SVMËùÓú˺¯ÊýÀàÐÍ£¬·ÖΪLINEAR=0, POLY=1, RBF=2, SIGMOID=3ÕâÈýÖÖ£¬ÎÄÖÐѵÁ·Êý¾Ý·ÖÀà½ÏΪ¼òµ¥£¬ÓÃÏßÐÔºËLINEAR=0¼´¿É
double degree£ºÓÃÀ´É趨¶àÏîʽÄں˺¯Êý£¨POLY=1£©µÄÃÝ´Î
double gamma£ºÓÃÀ´É趨Äں˺¯Êý£¨POLY/ RBF/ SIGMOID£©µÄ²ÎÊýgamma£¨¶àÏîʽϵÊý£©
double coef0£ºÓÃÀ´É趨Äں˺¯Êý£¨POLY/ RBF/ SIGMOID£©µÄ²ÎÊýcoef0£¨³£ÊýÏ
double C¡¢double nu¡¢double p¡¢CvMat* class_weights£ºÓÃÀ´É趨·ÇC_SVC=100ÀàÐ͵ÄÏàÓ¦²ÎÊý
CvTermCriteria term_crit£ºÓÃÀ´É趨SVMµü´úÖÕÖ¹Ìõ¼þ£¬Æä¹¹ÔìÀàÐÍΪ(int type, int max_iter, double expsolon)£¬Èý¸ö²ÎÊý·Ö±ðÒâΪ½áÊø·½Ê½£¨µü´ú´ÎÊýΪ»ù×¼µÄCV_TERMCRIT_ITER»òÎó²îֵΪ»ù×¼µÄCV_TERMCRIT_EPS£©£¬×î´óµü´ú´ÎÊý£¬×îСÎó²îÖµ
×ÛÉÏËùÊö£¬ÎÄÖÐSVM²ÎÊýÉèÖÃΪ£ºÒ»°ãSVM·ÖÀàÆ÷£¬ÏßÐԺˣ¬Ñ»·ÖÕÖ¹£¬100´ÎÑ»·£¬×îСÎó²îֵΪ¶¨ÒåFLT_EPSILON(1.192092896e-07F)¡£
ÉèÖÃÍê²ÎÊýºó£¬¾Í¸ÃÊÇSVMѵÁ·ÁË£¬ÓÉÓÚÀà³õʼ»¯ÐèÒªCvMat*Êý¾ÝÀàÐÍ£¬ÒÀ¾É½¨Òé³õʼ»¯Ò»¸ö¿ÕÀ࣬ÐèҪʲô²ÎÊýÓú¯ÊýÌí¼Ó£¬¾ßÌåÈçÏ£º
CvSVM SVM;
SVM.train(trainingDataMat, labelsMat, Mat(), Mat(),
params); |
svm.train¼´ÎªÑµÁ·º¯Êý£¬Æä²ÎÊýΪ
bool train( const
cv::Mat& trainData, const cv::Mat& responses,
const cv::Mat& varIdx=cv::Mat(), const cv::Mat&
sampleIdx=cv::Mat(),
CvSVMParams params=CvSVMParams() ) |
const cv::Mat& trainData£ºÑµÁ·Êý¾Ý¼¯£¬Ç°ÎÄÉ趨20*2µÄMat trainingDataMat£¬ÔÙ´ÎÌáÐѸñʽһ¶¨ÊÇCV_32FC1
const cv::Mat& responses£ºÏìÓ¦Êý¾Ý£¬¼´Ç°ÎĵÄѵÁ·Êý¾Ý±ê¼Ç£¬20*1µÄÏòÁ¿Mat labelsMat£¬¸ñʽ×îºÃÒ²ÊÇCV_32FC1
const cv::Mat& varIdx=cv::Mat(), const cv::Mat& sampleIdx=cv::Mat()£ºÁ½¸ö²ÎÊý±íʾ¸ÐÐËȤµÄÌØÕ÷ºÍÑù±¾£¬ÈçûÓиÐÐËȤ¶ÔÏóÔòÉèΪ¿Õ¾ØÕóMat()¼´¿É
CvSVMParams params=CvSVMParams()£ºSVM²ÎÊýÉ趨£¬¼´Ç°ÎÄÉ趨µÄCvSVMParams params
ÔËÐÐÍêtrainºó£¬Ñù±¾ÑµÁ·¹ý³Ì½áÊø£¬¿ÉÓÃSVM.predict()º¯Êý½øÐзÖÀ࣬ÓÃSVM.get_support_vector_count()º¯ÊýºÍSVM.get_support_vector()º¯Êý²é¿´Ö§³ÖÏòÁ¿£¬ÏÂÃæ·Ö±ð½éÉÜÈý¸öº¯Êý£º
float predict(
const cv::Mat& sample, bool returnDFVal=false
) const |
º¯Êý×÷ÓãºÅжÏsampleµÄÀà±ð
²ÎÊýconst Mat& sample£º´ý·ÖÀàÏòÁ¿£¬ÎÄÖÐѵÁ·Êý¾ÝÊǶþάÊý¾Ý£¬Òò´Ë´ý·ÖÀàÏòÁ¿Ó¦ÊÇ1*2µÄMat¾ØÕó£¬Êý¾ÝÀàÐÍӦΪfloatÐÍ(CV_32F)
²ÎÊýbool returnDFVal=false£ºÅжÏÊÇ·ñΪ¶þ·ÖÀàÆ÷£¬Í¨³£Çé¿öϲ»ÓÃÉ趨£¬Ä¬ÈÏfalse¼´¿É
·µ»ØÖµ£ºconst Mat& sampleµÄ·ÖÀà½á¹û£¬ÎÄÖзµ»ØÖµÓ¦ÎªÇ°ÎÄÉ趨µÄѵÁ·Êý¾Ý±ê¼ÇÖÖÀà1»ò-1
¼òµ¥Àý×Ó£º
float temp[2]
= { i, j };
Mat sampleMat(1, 2, CV_32F, temp);
float response = SVM.predict(sampleMat); |
int get_support_vector_count()
const
const float* get_support_vector(int i) const |
Á½¸öº¯Êý×÷ÓÃÊÇ»ñµÃÖ§³ÖÏòÁ¿£¬Í¨³£ÐèÒª½áºÏʹÓá£int get_support_vector_count()µÃµ½Ö§³ÖÏòÁ¿¸öÊý£¬½«½á¹û±éÀú´øÈëfloat* get_support_vector(int i)µÄ²ÎÊýi±ã¿É»ñµÃÿ¸öÖ§³ÖÏòÁ¿
¼òµ¥Àý×Ó£º
int c = SVM.get_support_vector_count();
for (int i = 0; i < c; ++i)
{const float* v = SVM.get_support_vector(i);} |
SVMº¯Êý´óÌåÈç´Ë£¬ÍêÕû´úÂë¼°×¢ÊÍ£º
#include <iostream>
#include <opencv.hpp>
using namespace std;
using namespace cv;
void main()
{
//É趨800*800µÄ¶þÎ¬×ø±êÆ½ÃæÇøÓò
int width = 800, height = 800;
Mat I = Mat::zeros(height, width, CV_8UC3);
//ѵÁ·Êý¾Ý¼¯£¬Ç°10¸ö±ê¼ÇΪ1£¬ºó10¸ö±ê¼ÇΪ-1
float trainingData[20][2] =
{ { 100, 100 }, { 200, 100 }, { 400, 100 },
{ 200, 200 }, { 500, 200 },
{ 100, 300 }, { 300, 300 }, { 400, 300 }, {
100, 400 }, { 200, 500 },
{ 600, 600 }, { 700, 300 }, { 700, 300 }, {
400, 500 }, { 600, 500 },
{ 200, 700 }, { 300, 600 }, { 500, 600 }, {
600, 300 }, { 400, 700 } };
//ѵÁ·Êý¾Ý¼¯´æÈë¾ØÕó
Mat trainingDataMat(20, 2, CV_32FC1, trainingData);
//ѵÁ·Êý¾Ý±ê¼Ç£¬Ç°10¸ö±ê¼ÇΪ1£¬ºó10¸ö±ê¼ÇΪ-1
float labels[20] =
{ 1.0, 1.0, 1.0, 1.0, 1.0,
1.0, 1.0, 1.0, 1.0, 1.0,
-1.0, -1.0, -1.0, -1.0, -1.0,
-1.0, -1.0, -1.0, -1.0, -1.0 };
//ѵÁ·Êý¾Ý±ê¼Ç´æÈë¾ØÕó
Mat labelsMat(20, 1, CV_32FC1, labels);
//½«ÑµÁ·Êý¾ÝÓò»Í¬ÑÕÉ«»³ö£º1ΪÂÌÉ«£¬-1ΪÀ¶É«
for (int i = 0; i < 20; i++)
{
if (labels[i] == 1.0)
circle(I, Point(trainingData[i][0], trainingData[i][1]),
2, Scalar(255, 0, 0), 2);
else
circle(I, Point(trainingData[i][0], trainingData[i][1]),
2, Scalar(0, 255, 0), 2);
}
imshow("dataset", I);
//SVM²ÎÊýÉèÖÃ
CvSVMParams params;
params.svm_type = CvSVM::C_SVC;
params.kernel_type = CvSVM::LINEAR;
params.term_crit = cvTermCriteria (CV_TERMCRIT_ITER,
100, FLT_EPSILON);
//SVMѵÁ·
CvSVM SVM;
SVM.train(trainingDataMat, labelsMat, Mat(),
Mat(), params);
//SVM·ÖÀà½á¹ûÏÔʾ£º1ÇøÓòΪÂÌÉ«£¬-1ÇøÓòΪÀ¶É«
for (int i = 0; i < I.rows; ++i)
for (int j = 0; j < I.cols; ++j)
{
float temp[2] = { i, j };
Mat sampleMat(1, 2, CV_32FC1, temp);
float response = SVM.predict(sampleMat);
if (response == 1)
I.at<Vec3b>(j, i) = Vec3b(255, 0, 0);
else if (response == -1)
I.at<Vec3b>(j, i) = Vec3b(0, 255, 0);
}
for (int i = 0; i < 20; i++)
{
if (labels[i] == 1.0)
circle(I, Point(trainingData[i][0], trainingData[i][1]),
2, Scalar(255, 255, 255), 2);
else
circle(I, Point(trainingData[i][0], trainingData[i][1]),
2, Scalar(0, 0, 0), 2);
}
//Ö§³ÖÏòÁ¿±ê×¢£¬ÓúìȦȦ³ö
int c = SVM.get_support_vector_count();
for (int i = 0; i < c; ++i)
{
const float* v = SVM.get_support_vector(i);
circle(I, Point((int)v[0], (int)v[1]), 6, Scalar(0,
0, 255), 2, 8);
}
imshow("result", I);
waitKey();
} |
·ÖÀà½á¹û£º
|