如何找到包含hog特征的Mat文件



我想训练一个基于HOG的分类器来检测视频中的行人,为此我已经计算了HOG特征并将它们存储在带有适当标记的文本文件中。我转向使用CvSVM实用程序,在那里我需要一个Mat对象携带的所有特征的整体样本(正面和负面)的信息。我发现这段代码可以将这些特征向量文件(文本文件)转换为Mat,但代码

Hogfeat.create(ders.size(),1,CV_32FC1);
for(int i=0;i<ders.size();i++)
{
  Hogfeat.at<float>(i,0)=ders.at(i);
}

提供断言错误。我可以看到错误是因为我的featureVector(每个图像)的大小为1*3780,但代码试图在每个新行加载featureVector。我的基本困惑的来源是"什么Mat文件的适当格式需要被馈送到CvSVM加载函数?"。这里给出了Mat格式的想法,但这是2个特征向量,即高度和宽度作为特征向量,行人检测应该是一样的吗?

这个示例应该包含我们在上面的注释中讨论过的情况。

//dummy readers
std:: vector<float> 
dummyDerReaderForOneDer(const vector<float> &pattern)
{
    int i = std::rand() % pattern.size();
    int j = std::rand() % pattern.size();
    vector<float> patternPulNoise(pattern);
    std::random_shuffle(patternPulNoise.begin()+std::min(i,j),patternPulNoise.begin()+std::max(i,j));
    return patternPulNoise;
};
std:: vector<float> 
dummyDerReaderForManyDers(const vector<float> &posPattern,
                                const vector<float> &negPattern, 
                                    vector<float> labels,
                                        float posLabel, float negLabel)
{
    int i,j;
    vector<float> allPatternsInOneVector;
    for(i=0;i< labels.size(); i++)
    {
        vector<float> patternPulNoise;
        if(labels[i]==posLabel)
        {
            patternPulNoise  = dummyDerReaderForOneDer(posPattern);
        }
        if(labels[i]==negLabel)
        {
            patternPulNoise  = dummyDerReaderForOneDer(negPattern);
        }
        for(j=0;j< patternPulNoise.size(); j++)
        {
            allPatternsInOneVector.push_back(patternPulNoise[j]);
        }
    }
    return allPatternsInOneVector;
}

// main harness entry point for detector test
int main (int argc, const char * argv[])
{
    //dummy variables for example
    int posFiles = 128;
    int negFiles = 128;
    int dims = 3780;
    //setup some dummy data
    vector<float> dummyPosPattern;
    dummyPosPattern.assign(1000,1.f);
    dummyPosPattern.resize(dims );
    random_shuffle(dummyPosPattern.begin(),dummyPosPattern.end());
    vector<float> dummyNegPattern;
    dummyNegPattern.assign(1000,1.f);
    dummyNegPattern.resize(dims );
    random_shuffle(dummyNegPattern.begin(),dummyNegPattern.end());
    // the labels and lables mat
    float posLabel = 1.f;
    float negLabel = 2.f;
    cv::Mat cSvmLabels;
    //the data mat
    cv::Mat cSvmTrainingData;
    //dummy linear svm parmas
    SVMParams cSvmParams;
    cSvmParams.svm_type = cv::SVM::C_SVC;
    cSvmParams.C = 0.0100;
    cSvmParams.kernel_type = cv::SVM::LINEAR;
    cSvmParams.term_crit =  cv::TermCriteria(CV_TERMCRIT_ITER+CV_TERMCRIT_EPS, 1000000, FLT_EPSILON);


    cout << "creating training data. please wait" << endl;
    int i;
    for(i=0;i<posFiles;i++)
    {
        //your feature for one box from file
        vector<float> d = dummyDerReaderForOneDer(dummyPosPattern);
        //push back a new mat made from the vectors data, with copy  data flag on
        //this shows the format of the mat for a single example, (1 (row) X dims(col) ), as  training mat has each **row** as an example;
        //the push_back works like vector add adds each example to the bottom of the matrix
        cSvmTrainingData.push_back(cv::Mat(1,dims,CV_32FC1,d.data(),true));
        //push back a pos label to the labels mat
        cSvmLabels.push_back(posLabel);
    }
    //do same with neg files;
    for(i=0;i<negFiles;i++)
    {
        float a =  rand(); 
        vector<float> d = dummyDerReaderForOneDer(dummyNegPattern);
        cSvmTrainingData.push_back(cv::Mat(1,dims,CV_32FC1,d.data(),true));
        cSvmLabels.push_back(negLabel);
    }
    //have a look
    cv::Mat viz;
    cSvmTrainingData.convertTo(viz,CV_8UC3);
    viz = viz*255;
    cv::imshow("svmData", viz);
    cv::waitKey(10);
    cout << "press any key to continue" << endl;
    getchar();
    viz.release();
    //create the svm;
    cout << "training, please wait" << endl;
    CvSVM svm;
    svm.train(cSvmTrainingData,cSvmLabels,cv::Mat(),cv::Mat(),cSvmParams);
    cout << "testing, please wait" << endl;
    //test the svm with a large amount of new unseen fake one at a time
    int totExamples = 10000;
    float TP(0.f), FP(0.f), FN(0.f), TN(0.f);
    for(i=0;i<totExamples; i++)
    {
        vector<float> dPos = dummyDerReaderForOneDer(dummyPosPattern);
        cv::Mat dMatPos(1,dims,CV_32FC1,dPos.data(),true);
        float predLabelPos = svm.predict(dMatPos);
        if(predLabelPos == posLabel) TP++;
        else(FN++);
        vector<float> dNeg = dummyDerReaderForOneDer(dummyNegPattern);
        cv::Mat dMatNeg(1,dims,CV_32FC1,dNeg.data(),true);
        float predLabelNeg = svm.predict(dMatNeg);
        if(predLabelNeg == negLabel) TN++;
        else(FP++);
        if(i%1000==0)
            cout << "testing " << i << "of " <<  totExamples << endl; 
    }
    //http://en.wikipedia.org/wiki/Precision_and_recall
    float sensitivity  = TP / (TP + FN);
    float specificity = TN / (TN + FP);
    float precision = TP / (TP + FP);
    cout << "sensitivity: " <<  sensitivity << endl;
    cout << "specificity: " <<  specificity << endl;
    cout << "precision: " <<  precision << endl;
    cout << "press any key to continue" << endl;
    getchar();
    cout << "creating test data, please wait" << endl;
    //test the svm with a large amount of new unseen fake data all at one time
    TP=FP=FN=TN = 0.f;
    vector<float> testLabels;
    for(i=0;i<int(totExamples/2);i++)
    {
        testLabels.push_back(posLabel);
    }
    for(i;i<totExamples;i++)
    {
        testLabels.push_back(negLabel);
    }

    vector<float> allExamples = dummyDerReaderForManyDers(dummyPosPattern,dummyNegPattern,testLabels,posLabel,negLabel);
    //on big mat
    cv::Mat allExamplesMat(1,allExamples.size(),CV_32FC1,allExamples.data(),true);
    //need reshape to one example per row
    allExamplesMat = allExamplesMat.reshape(0,totExamples);
    //have a look
    allExamplesMat.convertTo(viz,CV_8UC3);
    viz = viz*255;
    cv::imshow("testData", viz);
    cv::waitKey(10);
    cout << "press any key to continue" << endl;
    getchar();
    viz.release();
    //test them all at once ( uses intel tbb :)
    cout << "predict all at once, please wait" << endl;  
    cv::Mat predLabels_mat;
    svm.predict(allExamplesMat,predLabels_mat);
    //evaluate
    for(i=0;i<testLabels.size();i++)
    {
        float testLabel = testLabels.at(i);
        float predLabel = predLabels_mat.at<float>(i);
        if(testLabel==predLabel)
        {
            if(testLabel==posLabel) TP++;
            else TN++;
        }
        else
        {
            if(testLabel==posLabel) FP++;
            else FN++;
        }
    }
    //http://en.wikipedia.org/wiki/Precision_and_recall
    sensitivity  = TP / (TP + FN);
    specificity = TN / (TN + FP);
    precision = TP / (TP + FP);
    cout << "sensitivity: " <<  sensitivity << endl;
    cout << "specificity: " <<  specificity << endl;
    cout << "precision: " <<  precision << endl;
    cout << "press any key to continue" << endl;
    getchar();
    return(0);
}

最新更新