HOG特徵的SVM分類器訓練代碼

#include <cv.h>  
#include <io.h>  
#include <iostream>  
#include <string>  
#include <highgui.h>  
#include <ml.h>  
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] = "E:/work/INRIAPerson/pedestrianDetect-peopleFlow.txt";  
  
    string positivePath = "E:\\work\\INRIAPerson\\posgray\\";  
    string negativePath = "E:\\work\\INRIAPerson\\neggray\\";  
  
    int positiveSampleCount = 2416;  
    int negativeSampleCount = 3654;  
    int totalSampleCount = positiveSampleCount + negativeSampleCount;  
  
    cout<<"//////////////////////////////////////////////////////////////////"<<endl;  
    cout<<"totalSampleCount: "<<totalSampleCount<<endl;  
    cout<<"positiveSampleCount: "<<positiveSampleCount<<endl;  
    cout<<"negativeSampleCount: "<<negativeSampleCount<<endl;  
  
    CvMat *sampleFeaturesMat = cvCreateMat(totalSampleCount , 3780, 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+1);  
        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,128), 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+1);  
        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,128), 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 , 3780, CV_32FC1);  
    alp = cvCreateMat(1 , supportVectorSize, CV_32FC1);  
    re  = cvCreateMat(1 , 3780, 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*3780), svm.get_support_vector(i), 3780*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<3780; i++)  
    {  
        re->data.fl[i] *= -1;  
    }  
  
    FILE* fp = fopen("E:/work/INRIAPerson/hogSVMDetector-peopleFlow1.txt","wb");  
    if( NULL == fp )  
    {  
        return;  
    }  
    for(int i=0; i<3780; i++)  
    {  
        fprintf(fp,"%f \n",re->data.fl[i]);  
    }  
    float rho = svm.get_rho();  
    fprintf(fp, "%f", rho);  
    cout<<"E:/work/INRIAPerson/hogSVMDetector.txt 保存完畢"<<endl;//保存HOG能識別的分類器  
    fclose(fp);  
  
    return;  
}  
  
int main()  
{  
    Train();  
    return 0;  
}  


 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章