2013-09-30 30 views
0

我需要形成HOGDescriptor::setSVMDetector()输入。将LibSVM输出转换为浮点数矢量

我使用openCV计算描述符,然后使用libSVM获取模型文件。 为了形成输入,我知道我需要获得支持向量的值,并用alpha来元素化他们(然后在末尾添加-rho),但是我不知道从哪里得到这些alphas

我有这样的SV的列表:

1 1:-0.0434783 2:0.153846 3:0.194444 4:-0.353712 5:-0.45054 
1 1:-0.2173916 2:-0.38461 3:0.222262 4:-0.676686 5:-0.78062 

但是从哪里得到的阿尔法?

回答

0

好的,现在看来事情已经很清楚了。 阿尔法是第一列在我的情况。 因为我在我的测试模型中将它们全部等于-1或1(不知道为什么),所以我认为这些都是标签。

不管怎么说,这是我的解析器(但你需要离开仅颗卫星中的文件):

std::ifstream ifs("cars_model.model"); 

    const int nsv = 90; 
    const int nfeatures = 144; 

    float rho = 12.5459; 

    char ts[4000] = ""; // ! 

    std::vector<float> res(nfeatures,0); 

    std::vector<float> alphas; 

    Mat_<float> temp(nsv, nfeatures); 

    int c = 0; 

    std::cout << "Loading model file...\n"; 

    for (int i=0; i<nsv; i++) { 

     float al = 0; 
     ifs >> al; 
     alphas.push_back(al); 

     for (int j=0; j<nfeatures; j++) { 

      float ind, s; 
      char junk; 

      ifs >> ind >> junk >> s; 

      temp.at<float>(c, j) = s; 

      //std::cout << f << ' ' << s << '\n'; 

     } 

     c++; 

    } 

    ifs.close(); 

    std::cout << "Computing primal form...\n"; 

    for (int i=0; i<nsv; i++) { 

     float alpha = alphas[i]; 

     for (int j=0; j<nfeatures; j++) { 
      res[j] += (temp.at<float>(i,j) * alpha); 
     } 

    } 

    //res.push_back(-rho); 

    std::ofstream ofs("primal.txt"); 

    for (int i=0; i<res.size(); i++) 
     ofs << res[i] << ' '; 

    ofs.close(); 

而且你知道,它的作品。您可以将rho设置为检测器的阈值。

0

但你为什么要分类这个“手工”? OpenCV的has a classification routine称为predict,使用中发现的SV和阿尔法

float response = SVM.predict(sampleMat); 

如果你真的想自己做它,你将不仅需要颗卫星和阿尔法也用于培训和COMPUT内核函数

SUM alpha_i K(support_vector_i , data_point) - rho 

我不知道是否有可能提取阿尔法“手动”但不扩展SVM类,如可以在sources看到 - 阿尔法存储在CvSVMDecisionFunc结构:

struct CvSVMDecisionFunc 
{ 
    double rho; 
    int sv_count; 
    double* alpha; 
    int* sv_index; 
}; 

,而这种结构的唯一引用是protected部分:

protected: 

    (...) 

    CvSVMDecisionFunc* decision_func; 

svm.cpp的源代码,我们可以发现,这是只有通过save例行公开入店。因此,一些“黑客”将保存模型并从那里提取alpha(它将位于“Decision function”部分,用人类可读的格式编写)。

最简单的extracion技术似乎程度CvSVM类,并包括像澄清后

public: 

    CvSVMDecisionFunc* get_decision_function() { return decision_func; } 

更新

方法,即OP实际上是试图在OpenCV中使用externaly训练模型 - 最简单的方法是通过其他方法(libsvm,linearsvm等)将libsvm模型转换为opencv兼容格式并使用read方法将其转换为方法

void CvSVM::read(CvFileStorage* fs, CvFileNode* svm_node) 

see source for more details

+0

据我所知,你可以使用.predict(),但是你必须提供一个已经计算好的HOG用于一个完全相同大小的图像,就像你训练过的CvSVM一样,这是不方便的。如果你想使用扫描给定图像的例程,并返回一个点数组,它找到了答案,你应该使用.detectMultiScale()。 – degot

+0

我不太了解你的评论。支持向量机将总是**需要与训练中使用的输入大小相同的输入。无论您提取alpha还是使用预测方法都无关紧要,它将以相同的方式工作。 – lejlot

+0

好吧,首先,我决定不使用openCV进行培训,因为我发现了很多信息,人们说使用svmlight或libsvm更好,所以我不能使用CvSVMDecisionFunc。我所说的第二件事是detectMultiScale()获取任意大小的图像,并为您完成所有工作,在图像的每个点计算HOG,并返回匹配点。我对吗? – degot