程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> C# >> C#入門知識 >> 【EmguCV】C#實現HOG與SVM的幾個問題,

【EmguCV】C#實現HOG與SVM的幾個問題,

編輯:C#入門知識

【EmguCV】C#實現HOG與SVM的幾個問題,


 

關於SVM中的alpha、rho向量

由於EmguCV封裝的更加徹底,在C#中並不能跟C++一樣通過重載獲得這兩個中間變量

//繼承自CvSVM的類,因為生成setSVMDetector()中用到的檢測子參數時,需要用到訓練好的SVM的decision_func參數,  
//但通過查看CvSVM源碼可知decision_func參數是protected類型變量,無法直接訪問到,只能繼承之後通過函數訪問  
class MySVM : public CvSVM  
{  
public:  
    //獲得SVM的決策函數中的alpha數組  
    double * get_alpha_vector()  
    {  
        return this->decision_func->alpha;  
    }  
  
    //獲得SVM的決策函數中的rho參數,即偏移量  
    float get_rho()  
    {  
        return this->decision_func->rho;  
    }  
};

見C++實例:訓練SVM分類器進行HOG行人檢測 http://blog.csdn.net/pb09013037/article/details/41256945)


為了獲取這兩個變量用於自定義HOG檢測子,暫時想到的幾種辦法:

1、C#讀取生成的XML文件

分類器訓練好後一般需要進行保存,方便直接預測

SVM svm = new SVM();
bool trained = svm.Train(my_train.sampleFeatureMat, my_train.sampleLabelMat, null, null, p);
svm.Save(@"../HOG_SVM.xml");

這裡給出我的C#提取SVM參數方式:

(只用於提取訓練目標為1與-1兩類的XML文件,如果類型大於2,則有多個rho與alpha數組,需要進一步組合)

using System;
using System.Text;
using System.Xml;
using System.IO;


namespace HOG_SVM
{
    class GetData
    {
        public double[] alpha;
        public double rho;

        XmlDocument doc;        
        StreamReader sr;
        int sv_count;
        string alpha_str;

        public GetData()
        {
            doc = new XmlDocument();
            doc.Load(Form1.LOAD_PATH);
            XmlNode nodes = doc.DocumentElement;
            get_rho(nodes);
            getAlpha_str(nodes);
            getSv_count(nodes);
            getAlpha(); 
        }

        public void get_rho(XmlNode nodes)
        {
            if (nodes.HasChildNodes)
            {
                foreach (XmlNode node in nodes.ChildNodes)
                {
                    if (nodes.Name == "rho")
                    {
                        rho = Double.Parse(nodes.InnerText);
                        return;
                    }
                    get_rho(node);
                }
            }
        }

        public void getAlpha_str(XmlNode nodes)
        {
            if (nodes.HasChildNodes)
            {
                foreach (XmlNode node in nodes.ChildNodes)
                {
                    if (nodes.Name == "alpha")
                    {
                        //sr = new StreamReader(new Stream(nodes.InnerText));
                        alpha_str = nodes.InnerText;
                        return;
                    }
                    getAlpha_str(node);
                }
            }
        }

        public void getSv_count(XmlNode nodes)
        {
            if (nodes.HasChildNodes)
            {
                foreach (XmlNode node in nodes.ChildNodes)
                {
                    if (nodes.Name == "sv_count")
                    {
                        sv_count = int.Parse(nodes.InnerText);
                        return;
                    }
                    getSv_count(node);
                }
            }
        }
        
        public void getAlpha()
        {
            byte[] array = Encoding.ASCII.GetBytes(alpha_str);
            MemoryStream stream = new MemoryStream(array);             //convert stream 2 string      
            sr = new StreamReader(stream);
            alpha = new double[sv_count];
            sr.ReadLine();
            int i = 0;
            while (true)
            {

                string tmp = sr.ReadLine();
                if (tmp == "")
                    continue;

                string[] tmp2 = tmp.Split(' ');
                foreach (string ele in tmp2)
                {
                    if (ele != "")
                    {
                        alpha[i] = double.Parse(ele);
                        i++;
                    }
                }

                if (i == sv_count)
                    break;
            }
        }        
    }
}

c#讀取XML的方式比較多,還可以利用Linq操作xml,另外也可以參考以下鏈接:

c# 讀取opencv 生成的svm訓練好的xml分類器http://blog.csdn.net/yeyang911/article/details/12905153


 

2、使用其他C#的SVM庫

關於提取參數,自定義HOG Detector的問題,後來在網上搜到了這種方式

Training custom SVM to use with HOGDescriptor in OpenCV:

I was struggling with the same problem. Searching forums I have found, that the detector cannot be trained using CvSVM (I don't know the reason). I used LIBSVM for training the the detector. Here is the code to extract the detector for HOGDescriptor.setSVMDetector( w): For data details see LIBSVM documentation/header. I did all the training in C++, filling the LIBSVM training data from CV to LIBSVM; the code below extracts the detector vector needed for cv::HOGDescriptor. The w parameter is 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]);

來自: http://stackoverflow.com/questions/15339657/training-custom-svm-to-use-with-hogdescriptor-in-opencv


該回答提到的 LIBSVM 庫就是比較好的替代手段,應該可以直接獲取到這兩個中間量,而不用再去解析XML。

可以去作者主頁上下載LIBSVM庫:http://www.csie.ntu.edu.tw/~cjlin/libsvm/#csharp


 

3、其他相關鏈接

  • 前些天的【OpenCV】基於HOG與SVM的行人檢測學習(原理小結):

    http://www.cnblogs.com/KC-Mei/p/4534009.html

  • training GPU HOGDescriptor for multi scale detection:

    http://answers.opencv.org/question/4351/training-gpu-hogdescriptor-for-multi-scale-detection/

M$7{){(RJTFFR@RMUB{71QA

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved