码迷,mamicode.com
首页 > 其他好文 > 详细

HOG+SVM

时间:2015-09-08 12:35:34      阅读:410      评论:0      收藏:0      [点我收藏+]

标签:

  1. #include "cv.h"  
  2. #include "highgui.h"  
  3. #include "stdafx.h"  
  4. #include <ml.h>  
  5. #include <iostream>  
  6. #include <fstream>  
  7. #include <string>  
  8. #include <vector>  
  9. using namespace cv;  
  10. using namespace std;  
  11.   
  12.   
  13. int main(int argc, char** argv)    
  14. {    
  15.     vector<string> img_path;  
  16.     vector<int> img_catg;  
  17.     int nLine = 0;  
  18.     string buf;  
  19.     ifstream svm_data( "E:/SVM_DATA.txt" );  
  20.     unsigned long n;  
  21.   
  22.     while( svm_data )  
  23.     {  
  24.         if( getline( svm_data, buf ) )  
  25.         {  
  26.             nLine ++;  
  27.             if( nLine % 2 == 0 )  
  28.             {  
  29.                  img_catg.push_back( atoi( buf.c_str() ) );//atoi将字符串转换成整型,标志(0,1)  
  30.             }  
  31.             else  
  32.             {  
  33.                 img_path.push_back( buf );//图像路径  
  34.             }  
  35.         }  
  36.     }  
  37.     svm_data.close();//关闭文件  
  38.   
  39.     CvMat *data_mat, *res_mat;  
  40.     int nImgNum = nLine / 2;            //读入样本数量  
  41.     ////样本矩阵,nImgNum:横坐标是样本数量, WIDTH * HEIGHT:样本特征向量,即图像大小  
  42.     data_mat = cvCreateMat( nImgNum, 1764, CV_32FC1 );  
  43.     cvSetZero( data_mat );  
  44.     //类型矩阵,存储每个样本的类型标志  
  45.     res_mat = cvCreateMat( nImgNum, 1, CV_32FC1 );  
  46.     cvSetZero( res_mat );  
  47.   
  48.     IplImage* src;  
  49.     IplImage* trainImg=cvCreateImage(cvSize(64,64),8,3);//需要分析的图片  
  50.   
  51.     for( string::size_type i = 0; i != img_path.size(); i++ )  
  52.     {  
  53.             src=cvLoadImage(img_path[i].c_str(),1);  
  54.             if( src == NULL )  
  55.             {  
  56.                 cout<<" can not load the image: "<<img_path[i].c_str()<<endl;  
  57.                 continue;  
  58.             }  
  59.   
  60.             cout<<" processing "<<img_path[i].c_str()<<endl;  
  61.                  
  62.             cvResize(src,trainImg);   //读取图片     
  63.             HOGDescriptor *hog=new HOGDescriptor(cvSize(64,64),cvSize(16,16),cvSize(8,8),cvSize(8,8),9);  //具体意思见参考文章1,2     
  64.             vector<float>descriptors;//结果数组     
  65.             hog->compute(trainImg, descriptors,Size(1,1), Size(0,0)); //调用计算函数开始计算     
  66.             cout<<"HOG dims: "<<descriptors.size()<<endl;  
  67.             //CvMat* SVMtrainMat=cvCreateMat(descriptors.size(),1,CV_32FC1);  
  68.             n=0;  
  69.             for(vector<float>::iterator iter=descriptors.begin();iter!=descriptors.end();iter++)  
  70.             {  
  71.                 cvmSet(data_mat,i,n,*iter);  
  72.                 n++;  
  73.             }  
  74.                 //cout<<SVMtrainMat->rows<<endl;  
  75.             cvmSet( res_mat, i, 0, img_catg[i] );  
  76.             cout<<" end processing "<<img_path[i].c_str()<<" "<<img_catg[i]<<endl;  
  77.     }  
  78.       
  79.                
  80.     CvSVM svm = CvSVM();    
  81.     CvSVMParams param;    
  82.     CvTermCriteria criteria;    
  83.     criteria = cvTermCriteria( CV_TERMCRIT_EPS, 1000, FLT_EPSILON );    
  84.     param = CvSVMParams( CvSVM::C_SVC, CvSVM::RBF, 10.0, 0.09, 1.0, 10.0, 0.5, 1.0, NULL, criteria );    
  85. /*    
  86.     SVM种类:CvSVM::C_SVC    
  87.     Kernel的种类:CvSVM::RBF    
  88.     degree:10.0(此次不使用)    
  89.     gamma:8.0    
  90.     coef0:1.0(此次不使用)    
  91.     C:10.0    
  92.     nu:0.5(此次不使用)    
  93.     p:0.1(此次不使用)    
  94.     然后对训练数据正规化处理,并放在CvMat型的数组里。    
  95.                                                         */       
  96.     //☆☆☆☆☆☆☆☆☆(5)SVM学习☆☆☆☆☆☆☆☆☆☆☆☆         
  97.     svm.train( data_mat, res_mat, NULL, NULL, param );    
  98.     //☆☆利用训练数据和确定的学习参数,进行SVM学习☆☆☆☆     
  99.     svm.save( "SVM_DATA.xml" );    
  100.   
  101.     //检测样本  
  102.     IplImage *test;  
  103.     vector<string> img_tst_path;  
  104.     ifstream img_tst( "E:/SVM_TEST.txt" );  
  105.     while( img_tst )  
  106.     {  
  107.         if( getline( img_tst, buf ) )  
  108.         {  
  109.             img_tst_path.push_back( buf );  
  110.         }  
  111.     }  
  112.     img_tst.close();  
  113.   
  114.   
  115.   
  116.     CvMat *test_hog = cvCreateMat( 1, 1764, CV_32FC1 );  
  117.     char line[512];  
  118.     ofstream predict_txt( "SVM_PREDICT.txt" );  
  119.     for( string::size_type j = 0; j != img_tst_path.size(); j++ )  
  120.     {  
  121.         test = cvLoadImage( img_tst_path[j].c_str(), 1);  
  122.         if( test == NULL )  
  123.         {  
  124.              cout<<" can not load the image: "<<img_tst_path[j].c_str()<<endl;  
  125.                continue;  
  126.          }  
  127.           
  128.         cvZero(trainImg);  
  129.         cvResize(test,trainImg);   //读取图片     
  130.         HOGDescriptor *hog=new HOGDescriptor(cvSize(64,64),cvSize(16,16),cvSize(8,8),cvSize(8,8),9);  //具体意思见参考文章1,2     
  131.         vector<float>descriptors;//结果数组     
  132.         hog->compute(trainImg, descriptors,Size(1,1), Size(0,0)); //调用计算函数开始计算     
  133.         cout<<"HOG dims: "<<descriptors.size()<<endl;  
  134.         CvMat* SVMtrainMat=cvCreateMat(1,descriptors.size(),CV_32FC1);  
  135.         n=0;  
  136.         for(vector<float>::iterator iter=descriptors.begin();iter!=descriptors.end();iter++)  
  137.             {  
  138.                 cvmSet(SVMtrainMat,0,n,*iter);  
  139.                 n++;  
  140.             }  
  141.   
  142.         int ret = svm.predict(SVMtrainMat);  
  143.         sprintf( line, "%s %d\r\n", img_tst_path[j].c_str(), ret );  
  144.          predict_txt<<line;  
  145.     }  
  146.     predict_txt.close();  
  147.   
  148. //cvReleaseImage( &src);  
  149. //cvReleaseImage( &sampleImg );  
  150. //cvReleaseImage( &tst );  
  151. //cvReleaseImage( &tst_tmp );  
  152. cvReleaseMat( &data_mat );  
  153. cvReleaseMat( &res_mat );  
  154.   
  155. return 0;  

 

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 }

HOG+SVM

标签:

原文地址:http://www.cnblogs.com/zzh123/p/4791118.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!