如何找到由猪特征组成的Mat文件

时间:2014-08-02 10:59:08

标签: opencv svm

我想训练一个基于HOG的分类器来检测视频中的行人,为此我已经完成了计算生猪功能并将它们存储在带有适当标签的文本文件中。我转向使用CvSVM实用程序,我需要一个Mat对象,其中包含整个样本的所有featureVectors的信息(正面和负面)。我发现this代码可以将这些featureVector文件(文本文件)转换为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。我的基本混淆源是&#34; Mat文件的正确格式需要提供给CvSVM加载功能?&#34;。 here给出了Mat格式的概念,但是对于2个特征向量,即高度和宽度作为特征向量,对于行人检测也应该是相同的吗?

1 个答案:

答案 0 :(得分:0)

此示例应包含我们在评论中讨论过的案例。

//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);
}