2013-03-11 12 views
5

OpenCV :: HOGDescriptor ile kullanmak için kendi dedektörümü eğitmeye çalışıyorum ama mevcut HOGDescriptor'umu yeni eğitimli SVM'mle çalışmak konusunda sorun yaşıyorum.OpenCV'de HOGDescriptor ile kullanmak için özel SVM eğitimi

Pozitif ve negatif antrenman görüntüleri için HOG özelliklerini hesapladım, etiketledim ve CvSVM kullanarak SVM'yi eğitdim. Ben kullandım parametreler şunlardır: Ben sadece yerine birçok biri vektörü olsun ve HOGDescriptor.setSVMDetector (vektör) kullanılarak hesaplanan destek vektör set böylece

CvSVMParams params; 
    params.svm_type =CvSVM::EPS_SVR; 
    params.kernel_type = CvSVM::LINEAR; 
    params.C = 0.01; 
    params.p = 0.5; 

Sonra destek vektörlerin Primal Formu hesaplamak;

This is Primal Form

Ben CvSVM.predict() Ben doğru SVM nesneleri sınıflandırmak mümkün, ama HOGDescriptor.detect() veya detectMultiScale() her zaman pozitif eşleşmelerin bir sürü verir ve doğru vermez kullandığınızda tahminleri.

CvSVM.predict(), sınıflandırma için orijinal destek vektörlerini kullanır; bu nedenle, birincil form hesaplama biçiminde bir sorun olabilir.

Beni doğru yöne çevirebilecek kendi dedektörlerini eğiten biri var mı?

+0

Bu, libsvm'den bir etiketin sırasının bertaraf edildiği bir mirasın alınmış gibi görünüyor. Öngörme işlevi siparişin farkındadır ve hangi etiketin hangisi olduğunu inceler ve bu nedenle iyi çalışır. + Ve etiketimi, benim -ve one postanızdan daha az bir sayıya ayarlayarak sorunu çözdüm. Pos = 1, neg = 2. aksi takdirde modelinizi -1 ile çarparak tersine çevirmeniz gerekebilir. (Bu yüzden kabul edilen cevap garip olumsuz işarete sahip). Ben hata düzeltmek durumunda bu şekilde yapmamayı tercih ettim (bunu tahmin ederseniz gerçekten bir hata değil, ama değiştirebilir) – QED

cevap

6

hakkında mucit kağıdında önerilen bir lineer svm eğitildikten sonra primal formu çıkarmak için bir çocuk sınıfı CvSVM yazdım. Pozitif örnekler 1 etiketli ve negatif örnekler -1 olarak etiketlenmiştir. HogDescriptor'dan doğru sonuçlar almak için alfaların önüne negatif işaret koymak ve değişmeden rho işaretini bırakmak zorundayım.

LinearSVM.h

#ifndef LINEAR_SVM_H_ 
#define LINEAR_SVM_H_ 
#include <opencv2/core/core.hpp> 
#include <opencv2/ml/ml.hpp> 

class LinearSVM: public CvSVM { 
public: 
    void getSupportVector(std::vector<float>& support_vector) const; 
}; 

#endif /* LINEAR_SVM_H_ */ 

LinearSVM.cs

#include "linear_svm.h"  
void LinearSVM::getSupportVector(std::vector<float>& support_vector) const { 

    int sv_count = get_support_vector_count(); 
    const CvSVMDecisionFunc* df = decision_func; 
    const double* alphas = df[0].alpha; 
    double rho = df[0].rho; 
    int var_count = get_var_count(); 
    support_vector.resize(var_count, 0); 
    for (unsigned int r = 0; r < (unsigned)sv_count; r++) { 
     float myalpha = alphas[r]; 
     const float* v = get_support_vector(r); 
     for (int j = 0; j < var_count; j++,v++) { 
     support_vector[j] += (-myalpha) * (*v); 
     } 
    } 
    support_vector.push_back(rho); 
} 
+0

Çok güzel bir çözüm, sadece küçük bir soru @DXM: Bu ilk formata dönüştürme sadece Liner SVM için çalışır, ne zaman RBF çekirdekleri kullanırım? –

+1

Opencv'de RBF çekirdeğini kullanmanın kaynak koduna bakmadım. Ama benim tahminim, çekirdeği özelliklerine uyguladıktan sonra, lineer svm ile aynı olmalıdır. – DXM

+0

Bu, çok yavaş IMHO olabilir. Rbf çekirdeği, özellikler ve tüm svm destek vektörleri arasındaki öklid uzaklıklarını hesaplar. Metot koduna bir göz atın. Uygulamayı düşündüğünüz yolu merak ediyorum ... – Madhatter

4

Aynı problemle uğraşıyordum. Bulduğum forumlar, dedektörün CvSVM (nedenini bilmiyorum) kullanarak eğitilemediğini tespit ettim. Dedektörü eğitmek için LIBSVM kullanmıştım. İşte HOGDescriptor.setSVMDetector (w) için dedektörü ayıklamak için kod: Veri ayrıntıları için LIBSVM belgelerine/başlığına bakın. Tüm eğitimi C++ 'da yaptım, LIBSVM eğitim verilerini CV'den LIBSVM'ye doldurdum; Aşağıdaki kod, cv :: HOGDescriptor için gerekli olan dedektör vektörünü çıkarır. w parametresi Ben HOG dedektörü hakkında Dalal gazetelerde okumak kadarıyla bu yardımcı olur std::vector<float> w

const double * const *sv_coef = model.sv_coef; 
const svm_node * const *SV = model.SV; 
int l = model.l; 
model.label; 

const svm_node* p_tmp = SV[0]; 
int len = 0; 
while(p_tmp->index != -1) 
{ 
    len++; 
    p_tmp++; 
} 
w.resize(len+1); 

for(int i=0; i<l; i++) 
{ 
    double svcoef = sv_coef[0][i]; 
    const svm_node* p = SV[i]; 
    while(p->index != -1) 
    { 
     w[p->index-1] += float(svcoef * p->value); 
     p++; 
    } 
} 
w[len] = float(-model.rho[0]); 

Umut ...

+0

Bu kodu denediniz mi? Sahte görüntülerde bile + tespit eder gibi görünüyor. – magarwal

0

olduğunu, o yanlış pozitif kaldırmak önermek, bizim modeli yeniden eğitmek gerekir. Yeniden eğitim, ön modelin (yanlış pozitiflerin çoğunu veren modeliniz) uygulanmasıyla gerçekleştirilir, ardından tüm negatif örnek görüntülerde nesneleri tespit edilir. İade edilen tüm dikdörtgenler kesinlikle yanlış pozitif olur. Daha sonra, tüm bu yanlış pozitifleri negatif örnek resimlerinize ekleyin (negatif veri kümesi), bir kez daha eğitim yapın. Elde edilen model, kağıtta önerildiği gibi, daha az yanlış pozitif geri dönecektir. Bununla birlikte, maalesef bunu (yeniden eğitim) denedim, ancak ortaya çıkan model, pozitif görüntü örneklerinde bile hiçbir şeyi tanımıyor. Ama bence denemeye değer çünkü bu, HOG detektörü

İlgili konular