标签:
E:/SVM_TEST.txt和E:/SVM_TEST.txt的存放的都是这种格式的文件为:
d:/001.jpg
1
d:/002/jpg
0
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#include "cv.h"
#include "highgui.h"
#include <ml.h>
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
using namespace cv;
using namespace std;
class Mysvm: public CvSVM
{
public:
int get_alpha_count()
{
return this->sv_total;
}
int get_sv_dim()
{
return this->var_all;
}
int get_sv_count()
{
return this->decision_func->sv_count;
}
double* get_alpha()
{
return this->decision_func->alpha;
}
float** get_sv()
{
return this->sv;
}
float get_rho()
{
return this->decision_func->rho;
}
};
void Train()
{
char classifierSavePath[256] = "d:/pedestrianDetect-peopleFlow.txt";
string positivePath = "C:\\Users\\zzh\\Desktop\\Code-People_Detect - 副本\\pos\\";
string negativePath = "C:\\Users\\zzh\\Desktop\\Code-People_Detect - 副本\\neg\\";
int positiveSampleCount = 2;
int negativeSampleCount = 1;
int totalSampleCount = positiveSampleCount + negativeSampleCount;
cout<<"//////////////////////////////////////////////////////////////////"<<endl;
cout<<"totalSampleCount: "<<totalSampleCount<<endl;
cout<<"positiveSampleCount: "<<positiveSampleCount<<endl;
cout<<"negativeSampleCount: "<<negativeSampleCount<<endl;
CvMat *sampleFeaturesMat = cvCreateMat(totalSampleCount , 6824916, CV_32FC1);
//64*128的训练样本,该矩阵将是totalSample*3780,64*64的训练样本,该矩阵将是totalSample*1764
cvSetZero(sampleFeaturesMat);
CvMat *sampleLabelMat = cvCreateMat(totalSampleCount, 1, CV_32FC1);//样本标识
cvSetZero(sampleLabelMat);
cout<<"************************************************************"<<endl;
cout<<"start to training positive samples..."<<endl;
char positiveImgName[256];
string path;
for(int i=0; i<positiveSampleCount; i++)
{
memset(positiveImgName, ‘\0‘, 256*sizeof(char));
sprintf(positiveImgName, "%d.png", i);
int len = strlen(positiveImgName);
string tempStr = positiveImgName;
path = positivePath + tempStr;
cv::Mat img = cv::imread(path);
if( img.data == NULL )
{
cout<<"positive image sample load error: "<<i<<" "<<path<<endl;
system("pause");
continue;
}
cv::HOGDescriptor hog(cv::Size(64,64), cv::Size(16,16), cv::Size(8,8), cv::Size(8,8), 9);
vector<float> featureVec;
hog.compute(img, featureVec, cv::Size(8,8));
int featureVecSize = featureVec.size();
for (int j=0; j<featureVecSize; j++)
{
CV_MAT_ELEM( *sampleFeaturesMat, float, i, j ) = featureVec[j];
}
sampleLabelMat->data.fl[i] = 1;
}
cout<<"end of training for positive samples..."<<endl;
cout<<"*********************************************************"<<endl;
cout<<"start to train negative samples..."<<endl;
char negativeImgName[256];
for (int i=0; i<negativeSampleCount; i++)
{
memset(negativeImgName, ‘\0‘, 256*sizeof(char));
sprintf(negativeImgName, "%d.png", i);
path = negativePath + negativeImgName;
cv::Mat img = cv::imread(path);
if(img.data == NULL)
{
cout<<"negative image sample load error: "<<path<<endl;
continue;
}
cv::HOGDescriptor hog(cv::Size(64,64), cv::Size(16,16), cv::Size(8,8), cv::Size(8,8), 9);
vector<float> featureVec;
hog.compute(img,featureVec,cv::Size(8,8));//计算HOG特征
int featureVecSize = featureVec.size();
for ( int j=0; j<featureVecSize; j ++)
{
CV_MAT_ELEM( *sampleFeaturesMat, float, i + positiveSampleCount, j ) = featureVec[ j ];
}
sampleLabelMat->data.fl[ i + positiveSampleCount ] = -1;
}
cout<<"end of training for negative samples..."<<endl;
cout<<"********************************************************"<<endl;
cout<<"start to train for SVM classifier..."<<endl;
CvSVMParams params;
params.svm_type = CvSVM::C_SVC;
params.kernel_type = CvSVM::LINEAR;
params.term_crit = cvTermCriteria(CV_TERMCRIT_ITER, 1000, FLT_EPSILON);
params.C = 0.01;
Mysvm svm;
svm.train( sampleFeaturesMat, sampleLabelMat, NULL, NULL, params ); //用SVM线性分类器训练
svm.save(classifierSavePath);
cvReleaseMat(&sampleFeaturesMat);
cvReleaseMat(&sampleLabelMat);
int supportVectorSize = svm.get_support_vector_count();
cout<<"support vector size of SVM:"<<supportVectorSize<<endl;
cout<<"************************ end of training for SVM ******************"<<endl;
CvMat *sv,*alp,*re;//所有样本特征向量
sv = cvCreateMat(supportVectorSize , 1764, CV_32FC1);
alp = cvCreateMat(1 , supportVectorSize, CV_32FC1);
re = cvCreateMat(1 , 1764, CV_32FC1);
CvMat *res = cvCreateMat(1 , 1, CV_32FC1);
cvSetZero(sv);
cvSetZero(re);
for(int i=0; i<supportVectorSize; i++)
{
memcpy( (float*)(sv->data.fl+i*1764), svm.get_support_vector(i), 1764*sizeof(float));
}
double* alphaArr = svm.get_alpha();
int alphaCount = svm.get_alpha_count();
for(int i=0; i<supportVectorSize; i++)
{
alp->data.fl[i] = alphaArr[i];
}
cvMatMul(alp, sv, re);
int posCount = 0;
for (int i=0; i<1764; i++)
{
re->data.fl[i] *= -1;
}
FILE* fp = fopen("c:/hogSVMDetector-peopleFlow.txt","wb");
if( NULL == fp )
{
return ;
}
for(int i=0; i<1764; i++)
{
fprintf(fp,"%f \n",re->data.fl[i]);
}
float rho = svm.get_rho();
fprintf(fp, "%f", rho);
cout<<"c:/hogSVMDetector.txt 保存完毕"<<endl;//保存HOG能识别的分类器
fclose(fp);
return ;
}
void Detect()
{
CvCapture* cap = cvCreateFileCapture("E:\\02.avi");
if (!cap)
{
cout<<"avi file load error..."<<endl;
system("pause");
exit(-1);
}
vector<float> x;
ifstream fileIn("c:/hogSVMDetector-peopleFlow.txt", ios::in);
float val = 0.0f;
while(!fileIn.eof())
{
fileIn>>val;
x.push_back(val);
}
fileIn.close();
vector<cv::Rect> found;
cv::HOGDescriptor hog(cv::Size(64,64), cv::Size(16,16), cv::Size(8,8), cv::Size(8,8), 9);
hog.setSVMDetector(x);
IplImage* img = NULL;
cvNamedWindow("img", 0);
while(img=cvQueryFrame(cap))
{
hog.detectMultiScale(img, found, 0, cv::Size(8,8), cv::Size(32,32), 1.05, 2);
if (found.size() > 0)
{
for (int i=0; i<found.size(); i++)
{
CvRect tempRect = cvRect(found[i].x, found[i].y, found[i].width, found[i].height);
cvRectangle(img, cvPoint(tempRect.x,tempRect.y),
cvPoint(tempRect.x+tempRect.width,tempRect.y+tempRect.height),CV_RGB(255,0,0), 2);
}
}
}
cvReleaseCapture(&cap);
}
int main(int argc, char** argv)
{
Train() ;
vector<string> img_path;
vector<int> img_catg;
int nLine = 0;
string buf;
ifstream svm_data( "C:/Users/zzh/Desktop/Code-People_Detect/test.txt" );
unsigned long n;
while( svm_data )
{
if( getline( svm_data, buf ) )
{
nLine ++;
if( nLine % 2 == 0 )
{
img_catg.push_back( atoi( buf.c_str() ) );//atoi将字符串转换成整型,标志(0,1)
}
else
{
img_path.push_back( buf );//图像路径
}
}
}
svm_data.close();//关闭文件
CvMat *data_mat, *res_mat;
int nImgNum = nLine / 2; //读入样本数量
////样本矩阵,nImgNum:横坐标是样本数量, WIDTH * HEIGHT:样本特征向量,即图像大小
data_mat = cvCreateMat( nImgNum, 1764, CV_32FC1 );
cvSetZero( data_mat );
//类型矩阵,存储每个样本的类型标志
res_mat = cvCreateMat( nImgNum, 1, CV_32FC1 );
cvSetZero( res_mat );
IplImage* src;
IplImage* trainImg=cvCreateImage(cvSize(64,64),8,3);//需要分析的图片
for( string::size_type i = 0; i != img_path.size(); i++ )
{
src=cvLoadImage(img_path[i].c_str(),1);
if( src == NULL )
{
cout<<" can not load the image: "<<img_path[i].c_str()<<endl;
continue;
}
cout<<" processing "<<img_path[i].c_str()<<endl;
cvResize(src,trainImg); //读取图片
HOGDescriptor *hog=new HOGDescriptor(cvSize(64,64),cvSize(16,16),cvSize(8,8),cvSize(8,8),9); //具体意思见参考文章1,2
vector<float>descriptors;//结果数组
hog->compute(trainImg, descriptors,Size(1,1), Size(0,0)); //调用计算函数开始计算
cout<<"HOG dims: "<<descriptors.size()<<endl;
//CvMat* SVMtrainMat=cvCreateMat(descriptors.size(),1,CV_32FC1);
n=0;
for(vector<float>::iterator iter=descriptors.begin();iter!=descriptors.end();iter++)
{
cvmSet(data_mat,i,n,*iter);
n++;
}
//cout<<SVMtrainMat->rows<<endl;
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种类:CvSVM::C_SVC
Kernel的种类:CvSVM::RBF
degree:10.0(此次不使用)
gamma:8.0
coef0:1.0(此次不使用)
C:10.0
nu:0.5(此次不使用)
p:0.1(此次不使用)
然后对训练数据正规化处理,并放在CvMat型的数组里。
*/
//☆☆☆☆☆☆☆☆☆(5)SVM学习☆☆☆☆☆☆☆☆☆☆☆☆
svm.train( data_mat, res_mat, NULL, NULL, param );
//☆☆利用训练数据和确定的学习参数,进行SVM学习☆☆☆☆
svm.save( "SVM_DATA.xml" );
//检测样本
IplImage *test;
vector<string> img_tst_path;
ifstream img_tst( "C:/Users/zzh/Desktop/Code-People_Detect/test.txt" );
while( img_tst )
{
if( getline( img_tst, buf ) )
{
img_tst_path.push_back( buf );
}
}
img_tst.close();
CvMat *test_hog = cvCreateMat( 1, 1764, CV_32FC1 );
char line[512];
ofstream predict_txt( "SVM_PREDICT.txt" );
for( string::size_type j = 0; j != img_tst_path.size(); j++ )
{
test = cvLoadImage( img_tst_path[j].c_str(), 1);
if( test == NULL )
{
cout<<" can not load the image: "<<img_tst_path[j].c_str()<<endl;
continue;
}
cvZero(trainImg);
cvResize(test,trainImg); //读取图片
HOGDescriptor *hog=new HOGDescriptor(cvSize(64,64),cvSize(16,16),cvSize(8,8),cvSize(8,8),9); //具体意思见参考文章1,2
vector<float>descriptors;//结果数组
hog->compute(trainImg, descriptors,Size(1,1), Size(0,0)); //调用计算函数开始计算
cout<<"HOG dims: "<<descriptors.size()<<endl;
CvMat* SVMtrainMat=cvCreateMat(1,descriptors.size(),CV_32FC1);
n=0;
for(vector<float>::iterator iter=descriptors.begin();iter!=descriptors.end();iter++)
{
cvmSet(SVMtrainMat,0,n,*iter);
n++;
}
int ret = svm.predict(SVMtrainMat);
sprintf( line, "%s %d\r\n", img_tst_path[j].c_str(), ret );
predict_txt<<line;
}
predict_txt.close();
//cvReleaseImage( &src);
//cvReleaseImage( &sampleImg );
//cvReleaseImage( &tst );
//cvReleaseImage( &tst_tmp );
cvReleaseMat( &data_mat );
cvReleaseMat( &res_mat );
return 0;
}
/////////////////////////////////////////////////////////////////////////////////////////
283 int main(int argc, char** argv){ 284 285 //my_train(); 286 //my_detect(); 287 vector<float> x; 288 ifstream fileIn("e:/hogSVMDetector-peopleFlow.txt", ios::in); /* 读入支持向量,没必要读入样本的向量 */ 289 float val = 0.0f; 290 while(!fileIn.eof()) 291 { 292 fileIn>>val; 293 x.push_back(val); 294 } 295 fileIn.close(); 296 297 vector<Rect> found, found_filtered; 298 cv::HOGDescriptor hog(cv::Size(64,128), cv::Size(16,16), cv::Size(8,8), cv::Size(8,8), 9); 299 hog.setSVMDetector(x); 300 301 Mat img; 302 img=imread("1.jpg",0); 303 hog.detectMultiScale(img, found, 0, cv::Size(8,8), cv::Size(32,32), 1.05, 2); 304 size_t i, j; 305 for( i = 0; i < found.size(); i++ ) 306 { 307 Rect r = found[i]; 308 for( j = 0; j < found.size(); j++ ) 309 if( j != i && (r & found[j]) == r) 310 break; 311 if( j == found.size() ) 312 found_filtered.push_back(r); 313 } 314 for( i = 0; i < found_filtered.size(); i++ ) 315 { 316 Rect r = found_filtered[i]; 317 // the HOG detector returns slightly larger rectangles than the real objects. 318 // so we slightly shrink the rectangles to get a nicer output. 319 r.x += cvRound(r.width*0.1); 320 r.width = cvRound(r.width*0.8); 321 r.y += cvRound(r.height*0.07); 322 r.height = cvRound(r.height*0.8); 323 rectangle(img, r.tl(), r.br(), cv::Scalar(0,255,0), 3); 324 } 325 imshow("people detector", img); 326 waitKey(); 327 328 /*cvNamedWindow("img", 0); 329 string testimage="E:\database\picture_resize_pos\resize000r.bmp"; 330 Mat img=cv::imread(testimage); 331 hog.detectMultiScale(img, found, 0, cv::Size(8,8), cv::Size(32,32), 1.05, 2); 332 if (found.size() > 0) 333 { 334 printf("found!"); 335 }*/ 336 337 return 0; 338 339 }
标签:
原文地址:http://www.cnblogs.com/zzh123/p/4791118.html