1

我需要形成HOGDescriptor::setSVMDetector()输入。

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

我有一个 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

但是在哪里可以获得阿尔法?

4

2 回答 2

1

好的,现在事情似乎很清楚了。 就我而言, Alphas 是第一列。由于在我的测试模型中它们都等于 -1 或 1(不知道为什么),我认为这些是标签。

无论如何,这是我的解析器(但您只需要在文件中保留 SV):

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 设置为检测器的阈值。

于 2013-10-01T11:38:10.923 回答
0

但是为什么要“手动”分类呢?OpenCv 有一个名为的分类例程predict,它使用找到的 SVs' 和 alphas'

float response = SVM.predict(sampleMat);

如果你真的想自己做,你不仅需要 SV 和 alpha,还需要一个用于训练和计算的核函数

SUM alpha_i K( support_vector_i , data_point ) - rho

我不确定是否可以在不扩展 SVM 类的情况下“手动”提取 alpha,正如在源代码中看到的那样- alpha 存储在CvSVMDecisionFunc结构中:

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

而对该结构的唯一参考是在以下protected部分:

protected:

    (...)

    CvSVMDecisionFunc* decision_func;

从源代码中svm.cpp我们可以发现,它只能通过save例程公开访问。所以一些“hack”将是保存模型并从那里提取 alpha(它将位于“决策函数”部分,以人类可读的格式编写)。

最简单的提取技术似乎扩展了CvSVM类并包含方法,例如

public:

    CvSVMDecisionFunc* get_decision_function() { return decision_func; }

更新

澄清后,OP实际上正在尝试在opencv中使用外部训练模型-最简单的方法是将由其他方法(libsvm,linearsvm等)创建的libsvm模型转换为opencv兼容格式并使用read方法加载它

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

有关更多详细信息,请参阅来源

于 2013-09-30T09:21:52.260 回答