日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

libsvm Minist Hog 手写体识别

發布時間:2025/7/25 编程问答 20 豆豆
生活随笔 收集整理的這篇文章主要介紹了 libsvm Minist Hog 手写体识别 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.


統計手寫數字集的HOG特征

轉載請注明出處,樓燚(yì)航的blog,http://www.cnblogs.com/louyihang-loves-baiyan/

這篇文章是模式識別的小作業,利用svm實現Minist數據集手寫體識別,在這里我實現了opencv中的svm和libsvm兩個版本,供大家做參考。

[https://github.com/YihangLou/SVM-Minist-HandWriting-Recognition]https://github.com/YihangLou/SVM-Minist-HandWriting-Recognition?Github上的工程鏈接

Hog特征簡介

本實驗中,使用開源計算機視覺庫OpenCV作為圖像處理的基本工具,用其提供的loadImage函數讀入訓練樣本后,首先我們考慮如何對樣本中的手寫數字特征進行提取。在本實驗中我們采取了方向梯度直方圖(Histogram of OrientedGradient, HOG)的方法。HOG特征是一種在計算機視覺和圖像處理中用來進行物體檢測的特征描述子。在一副圖像中,局部目標的表象和形狀能夠被梯度和邊緣的方向密度分布很好地描述,而HOG通過計算和統計圖像局部區域的梯度方向直方圖來構成特征。

HOG特征提取算法的實現過程如下:

1)將待檢測的圖像灰度化;
2)采用Gamma校正法對輸入圖像進行顏色空間的標準化(歸一化)。目的是調節圖像的對比度,降低圖像局部的陰影和光照變化所造成的影響,同時可以抑制噪音的干擾。
3)計算圖像每個像素的梯度(包括大小和方向)。主要是為了捕獲輪廓信息,同時進一步弱化光照的干擾。
4)將圖像劃分成小cells(例如66像素/cell),并統計每個cell的梯度直方圖(不同梯度的個數),即可形成每個cell的descriptor。統計梯度直方圖過程如下:假設我們采用9個bin的直方圖來統計這66個像素的梯度信息。也就是將cell的梯度方向 分成9個方向塊,

如果這個像素的梯度方向 是 或者 ,直方圖第2個bin的計數就加1,這樣,對cell內每個像素用梯度方向在直方圖中進行加權投影(映射到固定的角度范圍),就可以得到這個cell的梯度方向直方圖了,就是該cell對應的9維特征向量(因為有9個bin)。梯度幅值 就是作為投影的權值的。例如說:這個像素的梯度方向是 ,然后它的梯度幅值 是2,那么直方圖第2個bin的計數就不是加1了,而是加2。
4)將每幾個cell組成一個block(例如3*3個cell/block),一個block內所有cell的特征descriptor串聯起來便得到該block的HOG特征descriptor;
5)將圖像image內的所有block的HOG特征descriptor串聯起來就可以得到該image的HOG特征descriptor了。這個就是最終的可供分類使用的特征向量了。

在我們的實驗中使用OpenCV提供的HOG算子HOGDescriotiptor,它的構造函數HOGDescriptor * hog = new HOGDescriptor(Size _winSize,Size _blockSize, Size _blockStride ,Size _cellSize , int bins);相關參數設置如表2.1所示。接下來我們只需再調用hog->compute()函數并以Image作為參數即可計算出其特征向量descriptors。
vectordescriptors;
hog->compute(Image, descriptors,Size(1,1), Size(0,0));

LibSVM配置

這里SVM的原理不就做介紹了,網上也有很多的資料介紹SVM

  • 首先設置SVM參數。LibSVM提供了SVM參數結構svm_param,如下段代碼所示,各參數意義如表2.2所示。
    //配置SVM參數
    svm_parameter param;
    param.svm_type = C_SVC;
    param.kernel_type = RBF;
    param.degree = 10.0;
    param.gamma = 0.09;
    param.coef0 = 1.0;
    param.nu = 0.5;
    param.cache_size = 1000;
    param.C = 10.0;
    param.eps = 1e-3;
    param.p = 1.0;

在本實驗中選擇了C_SVC類型的SVM,并且選擇了REF核函數。

  • 將待訓練的特征向量整理成LibSVM使用的數據格式。2.1.1中使用OpenCV提供的HOG方法得到了特征向量descriptors,要在LibSVM中使用上還需符合LibSVM的訓練數據文件格式,如下所示

    <label> <index1>:<value1> <index2>:<value2> ... 其中<label> 是訓練數據集的目標值,對于分類,它是標識某類的整數(支持多個類)。<index> 是以1開始的整數,可以是不連續的,但是必須在結尾處標記為index=-1;<value>為實數,也就是我們提取出的特征向量。例如我們處理第一張手寫圖片train_0_0.jpg,該圖片表示的是手寫數字0,那么<label>標記為0;該圖片用HOG方法描述的特征向量descriptor是長度為324的vector<float>,那么將<index1>~<index324>分別標記為0,1,2...323,<index325>標記為-1表示結束;<value1>~<value324>分別賦值為descriptor[0],descriptor[1],descriptor[2]...descriptor[323]。
  • 調用svm_train函數開始訓練,得到訓練模型svm_model,并保存于“*.model”文件。前面兩個步驟已經分別設置好了SVM的一系列參數param并整理了待訓練特征向量的格式svm_prob,svm_train函數以param和svm_prob作為參數開始訓練。

訓練過程中輸出如圖所示,其中, #iter為迭代次數;nu是選擇的核函數類型的參數;obj為SVM文件轉換為的二次規劃求解得到的最小值;rho為判決函數的偏置項b;nSV為標準支持向量個數(0<a[i]<c);nBSV為邊界上的支持向量個數(a[i]=c);Total nSV為支持向量總個數(對于兩類來說, 因為只有一個分類模型Total nSV = nSV但是對于多類,這個是各個分類模型的nSV之和)。
得到的“*.model”文件如下所示:

svm_type c_svc //所選擇的SVM類型,默認為c_svc kernel_type rbf //訓練采用的核函數類型, 此處為RBF核 gamma 0.09 //RBF核的參數γ nr_class 10 //類別數, 此處為數字0~9,即10個分類問題 total_sv 6364 //支持向量總個數 rho 1.57532 0.87752 -0.67652 0.45041 0.659519 -0.506248 0.534779 -1.06453 0.19707 -0.584892 -1.06272 -1.54669 -0.592897 -0.583714 -0.742219 -2.47223 -1.20282 -1.79853 -0.178512 -0.215509 -0.533352 0.286281 -1.75888 0.0187612 1.11297 2.04325 0.236593 0.855722 -0.836486 1.11822 0.096519 0.95863 -0.251392 -1.09347 -1.18159 -0.620122 0.237805 -2.51107 -0.453213 -0.0407495 -1.66436 -0.209359 -1.08233 -1.12835 1.5451//判決函數的偏置項b label 0 1 2 3 4 5 6 7 8 9 //原始文件中的類別標識 nr_sv 427 402 677 676 791 569 489 717 805 811//每個類的支持向量機的個數 ......

4)讀入測試集圖片,提取其HOG特征并整理成LibSVM使用的數據格式svm_node。測試集格式與訓練集格式的唯一不同在于測試集不需要標記label,也具有index和value屬性。
5)調用svm_predict函數進行測試。首先通過svm_model * 加載訓練出的模型“*.Model”,svm_model 和svm_node作為svm_predict函數的參數,該函數以返回一個int類型的數據,即預測出的類別。

OpenCV SVM

除了2.1.2介紹的LibSVM工具,我們小組還嘗試了OpenCV提供的SVM工具,它是基于LibSVM軟件包開發的,優點是使用起來比LibSVM更簡潔,下面簡要的介紹一下OpenCV中SVM的訓練和測試兩階段:
1)OpenCV中的SVM在訓練階段代碼如下所示:

void trainSVM(CvMat * & dataMat,CvMat * & labelMat ) {cout<<"train svm start"<<endl;cout<<dataMat<<endl;CvSVM svm;CvSVMParams param;//這里是SVM訓練相關參數 CvTermCriteria criteria; //這里是迭代終止準則 criteria = cvTermCriteria( CV_TERMCRIT_EPS, 1000, FLT_EPSILON ); param = CvSVMParams( CvSVM::C_SVC, CvSVM::RBF, 10.0, 0.09, 1.0, 10.0, 0.5, 1.0, NULL, criteria ); svm.train( dataMat, labelMat, NULL, NULL, param );//訓練數據 svm.save( SVMModel.c_str()); cout<<"SVM Training Complete"<<endl; }

其中CvTermCriteria設置了迭代終止準則,最大迭代次數設為1000次,結果的精確性設為FLT_EPSILON = 1.19e-7;CvSVMParams設置了SVM相關的訓練參數,參數具體設置仍如表2.1所示。與LibSVM不同的是,OpenCV不需要將特征向量整理成特定的格式,只需要特征向量按行順序排好,給出它們的label,就可以調用訓練函數svm.train()進行訓練了。另外,OpenCV訓練出的模型保存在“.xml”文件中而非LibSVM中的“.Model”文件,如圖2.3所示。

最后所有的支持向量個數為6364個,與LibSVM完全一致,印證了OpenCV SVM底層是基于LibSVM的。

2)在測試階段,OpenCV SVM的用法與LibSVM基本一致,調用svm.predict函數進行測試。首先通過CvSVM svm加載訓練出的模型“*.xml”。接著將測試集圖片的HOG向量整理成一個個CvMat,它作為svm_predict函數的參數輸入,該函數以返回一個int類型的數據,即預測出的類別。

代碼解讀

實驗代碼實現了LibSVM 和OpenCV SVM分類功能,完成了各個函數功能的封裝,整個SVM分類器共分為8個函數,分別為:readTrainFileList、processHogFeature、trainSVM、trainLibSVM,readTestFileList,testLibSVM,testSVM,releaseAll。其中,每個函數的輸入輸出設置以及功能如下表所示:

實驗測試

本次實驗使用“MNIST DATABASE”, 數據集包含了0-9數字手寫體,共有60000張訓練數據集,10000張測試數據集。測試集的前5000個例子取自原始NIST訓練集,后5000取自原始NIST測試集,前5000個數據要比后5000個數據更干凈、容易。
預測結果是輸出到txt中的,通過Python腳本來分析

1)訓練正確率
在訓練集上進行正確率測試得到的結果是0.9884。
2)測試正確率
在10000張測試數據集上,我們的實驗結果準確率為0.9884,其中10*10的舉證結果如下,結果(i,j)代表將第i類錯分為第j類的次數。

實驗的主要錯分類分析

實驗中,有一些錯分類很難避免,如4和9的錯分以及7和2的錯分,如下圖所示。由于實驗數據本身難以識別,造成的錯分占據整個實驗數據的1%左右。

總結

以上是生活随笔為你收集整理的libsvm Minist Hog 手写体识别的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。