资源描述
【转】 想写一个关于OpenCV的支持向量机SVM的程序2011-02-25 15:31转载自 dreamflyman最终编辑 dreamflyman作者:彭军
以前写过神经网络方面的程序,当然了,只是简单的BP神经网络了,因为是自己实现的,所以也相对比较简单。以前也曾经想过写个支持向量机的程序,可是看了很长时间还是没有什么概念,索性这次就借着OpenCV写一个支持向量机SVM的程序吧,好至少知道怎么用OpenCV来用支持向量机SVM做分类。
程序如下:
//////////////////////////////////////////////////////////////////////////
// File Name: pjSVM.cpp
// Author: easyfov(easyfov@)
// Company: Lida Optical and Electronic Co.,Ltd.
//////////////////////////////////////////////////////////////////////////
#include <cv.h>
#include <highgui.h>
#include <ml.h>
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
using namespace std;
#define WIDTH 28
#define HEIGHT 30
int main( /*int argc, char** argv*/ )
{
vector<string> img_path;
vector<int> img_catg;
int nLine = 0;
string buf;
ifstream svm_data( "SVM_DATA.txt" );
while( svm_data )
{
if( getline( svm_data, buf ) )
{
nLine ++;
if( nLine % 2 == 1 )
{
img_catg.push_back( atoi( buf.c_str() ) );
}
else
{
img_path.push_back( buf );
}
}
}
svm_data.close();
CvMat *data_mat, *res_mat;
int nImgNum = nLine / 2;
data_mat = cvCreateMat( nImgNum, WIDTH * HEIGHT, CV_32FC1 );
cvSetZero( data_mat );
res_mat = cvCreateMat( nImgNum, 1, CV_32FC1 );
cvSetZero( res_mat );
IplImage *srcImg, *sampleImg;
float b;
DWORD n;
for( string::size_type i = 0; i != img_path.size(); i++ )
{
srcImg = cvLoadImage( img_path[i].c_str(), CV_LOAD_IMAGE_GRAYSCALE );
if( srcImg == NULL )
{
cout<<" can not load the image: "<<img_path[i].c_str()<<endl;
continue;
}
cout<<" processing "<<img_path[i].c_str()<<endl;
sampleImg = cvCreateImage( cvSize( WIDTH, HEIGHT ), IPL_DEPTH_8U, 1 );
cvResize( srcImg, sampleImg );
cvSmooth( sampleImg, sampleImg );
n = 0;
for( int ii = 0; ii < sampleImg->height; ii++ )
{
for( int jj = 0; jj < sampleImg->width; jj++, n++ )
{
b = (float)((int)((uchar)( sampleImg->imageData + sampleImg->widthStep * ii + jj )) / 255.0 );
cvmSet( data_mat, (int)i, n, b );
}
}
cvmSet( res_mat, i, 0, img_catg[i] );
cout<<" end processing "<<img_path[i].c_str()<<" "<<img_catg[i]<<endl;
}
CvSVM svm = CvSVM();
CvSVMParams param;
CvTermCriteria criteria;
criteria = cvTermCriteria( CV_TERMCRIT_EPS, 1000, FLT_EPSILON );
param = CvSVMParams( CvSVM::C_SVC, CvSVM::RBF, 10.0, 0.09, 1.0, \
10.0, 0.5, 1.0, NULL, criteria );
svm.train( data_mat, res_mat, NULL, NULL, param );
svm.save( "SVM_DATA.xml" );
IplImage *tst, *tst_tmp;
vector<string> img_tst_path;
ifstream img_tst( "SVM_TEST.txt" );
while( img_tst )
{
if( getline( img_tst, buf ) )
{
img_tst_path.push_back( buf );
}
}
img_tst.close();
CvMat *tst_mat = cvCreateMat( 1, WIDTH*HEIGHT, CV_32FC1 );
char line[512];
ofstream predict_txt( "SVM_PREDICT.txt" );
for( string::size_type j = 0; j != img_tst_path.size(); j++ )
{
tst = cvLoadImage( img_tst_path[j].c_str(), CV_LOAD_IMAGE_GRAYSCALE );
if( tst == NULL )
{
cout<<" can not load the image: "<<img_tst_path[i].c_str()<<endl;
continue;
}
tst_tmp = cvCreateImage( cvSize( WIDTH, HEIGHT ), IPL_DEPTH_8U, 1 );
cvResize( tst, tst_tmp );
cvSmooth( tst_tmp, tst_tmp );
n = 0;
for(int ii = 0; ii < tst_tmp->height; ii++ )
{
for(int jj = 0; jj < tst_tmp->width; jj++, n++ )
{
b = (float)(((int)((uchar)tst_tmp->imageData+tst_tmp->widthStep*ii+jj))/255.0);
cvmSet( tst_mat, 0, n, (double)b );
}
}
int ret = svm.predict( tst_mat );
sprintf( line, "%s %d\r\n", img_tst_path[j].c_str(), ret );
predict_txt<<line;
}
predict_txt.close();
cvReleaseImage( &srcImg );
cvReleaseImage( &sampleImg );
cvReleaseImage( &tst );
cvReleaseImage( &tst_tmp );
cvReleaseMat( &data_mat );
cvReleaseMat( &res_mat );
return 0;
}
将训练完的SVM的数据都保存到了一个SVM_DATA.xml文件中,部分内容如下:
<?xml version="1.0"?>
<opencv_storage>
<my_svm type_id="opencv-ml-svm">
<svm_type>C_SVC</svm_type>
<kernel><type>RBF</type>
<gamma>0.0900000000000000</gamma></kernel>
<C>10.</C>
<term_criteria><epsilon>1.1920928955078125e-007</epsilon>
<iterations>2147483647</iterations></term_criteria>
<var_all>840</var_all>
<var_count>840</var_count>
<class_count>2</class_count>
<class_labels type_id="opencv-matrix">
<rows>1</rows>
<cols>2</cols>
<dt>i</dt>
<data>
0 1</data></class_labels>
<sv_total>26</sv_total>
<support_vectors>
<_>
0.37647060 0.38039216 0.38431373 0.38823530 0.39215687 0.39607844
0.40000001 0.40392157 0.40784314 0.41176471 0.41568628 0.41960785
0.42352942 0.42745098 0.43137255 0.43529412 0.43921569 0.44313726
0.44705883 0.45098040 0.45490196 0.45882353 0.46274510 0.46666667
0.47058824 0.47450981 0.47843137 0.48235294 0.48627451 0.49019608
0.49411765 0.49803922 0.50196081 0.50588238 0.50980395 0.51372552
0.51764709 0.52156866 0.52549022 0.52941179
看起来数值都比较正常,可是用predict方法的时候,得到的结果却让人失望,鬼知道为什么。
SVM_DATA.txt中内容如下:
0
G:/program/pjSVM/face/1.png
0
G:/program/pjSVM/face/2.png
0
G:/program/pjSVM/face/3.png
0
G:/program/pjSVM/face/4.png
0
G:/program/pjSVM/face/5.png
0
G:/program/pjSVM/face/6.png
0
G:/program/pjSVM/face/7.png
0
G:/program/pjSVM/face/8.png
0
G:/program/pjSVM/face/9.png
0
G:/program/pjSVM/face/10.png
0
G:/program/pjSVM/face/11.png
0
G:/program/pjSVM/face/12.png
0
G:/program/pjSVM/face/13.png
0
G:/program/pjSVM/face/14.png
0
G:/program/pjSVM/face/15.png
1
G:/program/pjSVM/face/16.png
1
G:/program/pjSVM/face/17.png
1
G:/program/pjSVM/face/18.png
1
G:/program/pjSVM/face/19.png
1
G:/program/pjSVM/face/20.png
1
G:/program/pjSVM/face/21.png
1
G:/program/pjSVM/face/22.png
1
G:/program/pjSVM/face/23.png
1
G:/program/pjSVM/face/24.png
1
G:/program/pjSVM/face/25.png
1
G:/program/pjSVM/face/26.png
1
G:/program/pjSVM/face/27.png
1
G:/program/pjSVM/face/28.png
1
G:/program/pjSVM/face/29.png
1
G:/program/pjSVM/face/30.png
SVM_TEST.txt中内容如下:
G:/program/pjSVM/try_face/5.png
G:/program/pjSVM/try_face/9.png
G:/program/pjSVM/try_face/11.png
G:/program/pjSVM/try_face/15.png
G:/program/pjSVM/try_face/2.png
G:/program/pjSVM/try_face/30.png
G:/program/pjSVM/try_face/17.png
G:/program/pjSVM/try_face/21.png
G:/program/pjSVM/try_face/24.png
G:/program/pjSVM/try_face/27.png
展开阅读全文