【问题标题】:How to find Mat file consisting of hog features如何找到包含 hog 特征的 Mat 文件
【发布时间】:2014-09-25 11:41:01
【问题描述】:

我想训练一个基于 HOG 的分类器来检测视频中的行人,为此我已经计算了 hog 特征并将它们存储在带有适当标签的文本文件中。我正在转向使用 CvSVM 实用程序,并且我需要一个 Mat 对象,该对象携带整个样本(正和负)的所有特征向量的信息。我发现this 代码可以将那些特征向量文件(文本文件)转换为 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。我的基本困惑来源是“需要提供给 CvSVM 加载函数的 Mat 文件的正确格式是什么?”。 here 给出了 Mat 格式的概念,但这是针对 2 个特征向量,即高度和宽度作为特征向量,行人检测也应该相同吗?

【问题讨论】:

  • 请提供更多信息。答:什么是ders? (一个向量,arrar,数组的向量,array,tomato)什么是Hogfeat?如果 Hogfeat 是一个 cv::Mat 那么请修改你的代码,好像我们不知道这些东西是什么,那么我们怎么可能告诉你如何复制/移动它们,想想吧!这向您展示了格式,请按照示例进行操作。 docs.opencv.org/doc/tutorials/ml/introduction_to_svm/…
  • 我以为你会从我提供的链接中得到这个想法。好吧,它是一个点向量,用于存储每张图像的 HOG 特征。 “Hogfeat”是 Mat 对象,它将存储这些特征,以便可以将其馈送到您提供的链接中第 28 行的函数,here
  • 但是要使该功能正常工作,此 Mat 对象应该具有正确的格式,这就是我不清楚如何将这些功能放置在 Mat 对象中的地方!
  • 好的,在这种情况下,您需要将其分解回每个框的向量。图像可能包含许多框,因此会造成混淆。要分解长向量,您需要知道描述符大小。然后使用 cv::Mat boxDescriptor(1,descriptorSize ,CV_32FC1,OneBoxDescVector.data(),true) 简单地从每个特征向量创建一个垫子;构造函数。您可以将 push_back 放入垫子中,也可以像矢量一样。因此,您可以对所有框 allDataMat.push_back(cv::Mat(1,descriptorSize ,CV_32FC1,allBoxDescVector[i].data(),true)) 其中 allBoxDescVector 是 vector> ,每个条目都是其中之一德斯
  • ^^请注意这是descriptorSize,而不是ders.size(),ders.size = no.of box * descriptorSize。 (你可以像你一样在复制后尝试重塑,但我自己没有尝试过。重塑为descriptorSize X no.of box,它期望矩阵的每行都有一个描述符)

标签: opencv svm


【解决方案1】:

这个样本应该包含我们上面在 cmets 中讨论过的案例。

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

【讨论】:

  • 你真好@QED。我了解您的代码流程,并且您的风格很棒。我不明白的一件事是第一个函数“std::random_shuffle(patternPulNoise.begin()+std::min(i,j),patternPulNoise.begin‌​()+std::max(i, j)); "它与读取描述符值有什么关系?如我所见,它只是在改变功能!我必须提到“viz”的东西很棒,但不幸的是我不知道它揭示了什么:(但是非常感谢您的宝贵时间!
  • 嗨,这只是一个模拟特征向量的虚拟函数,随机洗牌只是确保每个模拟特征彼此略有不同,以便进行更真实的测试。您不需要这些功能,您将生成/读取真实功能。
  • 由于您使用了两个不同的循环,每个循环一个,即预测和测试,所以 b/w 预测和测试集有什么区别。
  • 一个,使用 1 个特征来预测一个实例,另一个将许多实例放入一个矩阵中并对所有实例进行预测,然后返回一组预测,每个示例一个。这主要是为了说明在创建巨大的垫子后需要对矩阵进行重塑。
  • 好的。现在我想在检测()函数中使用这个训练有素的模型,为此它应该是单行向量形式,对吗?为此,我关注this。但我不知道如何获得这些 alpha 值。你能告诉我在哪里可以找到它们吗?你认为代码写得好吗?
猜你喜欢
  • 1970-01-01
  • 2014-01-01
  • 1970-01-01
  • 2012-09-22
  • 2014-08-11
  • 2016-07-19
  • 2016-05-07
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多