2013-09-30 3 views
0

Мне нужно сформировать HOGDescriptor::setSVMDetector().Преобразование вывода LibSVM в вектор поплавков

Я вычисляю дескрипторы с помощью openCV, затем использую libSVM для получения файла модели. Чтобы сформировать ввод, я знаю, что мне нужно получить значения векторов поддержки и поэлементно умножить их на альфа (тогда добавьте -rho в конце), но Я не понимаю, где можно получить эти альфы.

У меня есть список КТС, как:

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

Хорошо, теперь все ясно. Alphas - это первая колонка в моем случае. Поскольку у меня все они были равны -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, который использует нашел КУ и альфы

float response = SVM.predict(sampleMat); 

Если вы действительно хотите сделать это самостоятельно, вы бы не только нужно SVs и альфа, но и функция ядра используется для обучения и вычислый

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 рутина. Таким образом, некоторые «взломать» будут состоять в том, чтобы сохранить модель и извлечь из нее альфы (она будет находиться в разделе «Функция принятия решений», написанном в человекообразном формате).

Самый простой метод extracion кажется, насколько CvSVM класса и включают в себя метод, как

public: 

    CvSVMDecisionFunc* get_decision_function() { return decision_func; } 

обновление

после разъяснений, что OP действительно пытается использовать externaly обученную модель в OpenCV - самый простой способ для преобразования модели libsvm, созданной другим способом (libsvm, linearsvm и т. д.) в формат, совместимый с opencv, и загрузить его с использованием метода read

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

see source for more details.

+0

Как я понял, вы можете использовать .predict(), но вы должны предоставить ему уже вычисленную HOG для изображения такого же размера, как вы обучили CvSVM, и это неудобно. Если вы хотите использовать процедуру, которая сканирует данное изображение, и возвращает массив точек, где он нашел ответ, вы должны использовать .detectMultiScale(). – degot

+0

Я не совсем понимаю ваш комментарий. SVM всегда будет ** требовать того же размера ввода, что и в ходе обучения. Неважно, извлекаете ли вы альфа или используете метод прогнозирования, он будет работать одинаково. – lejlot

+0

Ну, во-первых, я решил не использовать openCV для обучения, потому что я нашел много информации, где люди говорят, что лучше использовать svmlight или libsvm, поэтому я не могу использовать CvSVMDecisionFunc. Во-вторых, я говорю о том, что detectMultiScale() принимает изображение ЛЮБОГО размера и выполняет всю работу за вас, вычисляя HOG в каждой точке изображения и возвращая соответствующие точки. Я прав? – degot

Смежные вопросы