2013-05-26 31 views
2

我正在開發一個使用OpenCV LibSVM的手寫字符識別系統。我已經提取了包括Hu矩,仿射不變矩,拐角數等特徵向量的14個特徵。對於每個字符,我使用5個樣本(對於字母「A」,有5個類型的A)。我知道5個樣本是不夠的,但是在我每個角色只有5個樣本的時候。如何在OpenCV和C++中爲CvSVM配置圖像分類

我在opencv文檔中使用基本的LINEAR SVM示例。我的問題是,我可以使用該文檔示例,因爲我的目的。我已閱讀了使用多類SVM的OCR系統。我的應用程序是否需要這種多級SVM?我不明白這一點。請有人解釋一下嗎?這是我的代碼。

我有180個數字和英文大寫字母樣本,一個樣本有14個特徵。

float labels[180][1] = {1.0, 2.0, 3.0, 4.0, 5.0, ,,,,, -> 180.0}; 
Mat matlabesls(180,1, CV_32FC1, labels); 

Mat mattrainingDataMat(180, 14, CV_32FC1, ifarr_readtrainingdata); 
CvSVMParams params; 

params.svm_type = CvSVM::C_SVC; 
params.kernel_type = CvSVM::LINEAR; 
params.term_crit = cvTermCriteria(CV_TERMCRIT_ITER, 100, 1e-6); 

CvSVM SVM; 
SVM.train(mattrainingDataMat,matlabesls,Mat(),Mat(),params); 

Mat matinput(1,14,CV_32FC1,ifarr_testarray); 
is_recognizedcharacter= SVM.predict(matinput); 

return is_recognizedcharacter; 

回答

8

標籤的設置不正確。您已定義了180個獨特標籤,但您只有26個類別的數據。在lengeth中標籤應該是180,但它應該只包含值1..26(任何26個不同的值將會這樣做),其順序與mattrainingDataMat中的字符順序一致。

您將需要更喜歡每個字母5000個樣本,而不僅僅是5個。您可以從MNIST手寫數字數據集開始,直到您有適當的數據。

你的代碼似乎在訓練svm來識別1個字符。你不應該那樣做,因爲它可能需要花費很長的時間來訓練svm。您應該單獨訓練svm並保存模型,以便可以重複使用,而無需每次都重新訓練。

我的理解是,OpenCV中的svm代碼是基於版本的Libsvm的版本。所以我直接使用libsvm的最新版本而不是OpenCV版本。另外,對於你的情況,你幾乎肯定會得到比線性內核更好的RBF內核精度(儘管線性更容易訓練)。看起來你有26個類,所以當然你需要一個多類SVM(這實際上只是許多二進制SVM) - Libsvm爲你處理多類問題。

+0

嗨,非常感謝你考慮我的問題。我更改代碼如下。我有36班(26個字母,10位數字)。目前我只使用5個樣本(直到我清楚瞭解)。一個班級有5個樣本,一個樣本有14個特徵。那麼對於一個班級有70個特徵(5 * 14)。你是這個意思嗎 ?? plz help .. \t'浮標[36] [1] = {1.0,2.0,... - > 36.0}; Mat matlabesls(36,1,CV_32FC1,labels) Mat mattrainingDataMat(36,70,CV_32FC1,ifarr_readtrainingdata);' –

+0

如果您的數據包含'A'的3個示例的特徵,'C'的2個和'5'的3個(按該順序)的特徵,則您的標籤將爲'浮動標籤[7] [1] = {11.0 ,11.0,11.0,13.0,13,0,5.0,5.0,5.0},假設0.0..9.0被用來標記'0'到'9'並且11.0..35.0被用來標記'A'。'Z' 。如果您的數據順序混亂了,標籤將需要拼湊起來才能匹配。標籤告訴SVM每個數據項是什麼樣的。 – Bull

+0

非常感謝你,我瞭解標籤。你能告訴我關於多分類SVM在這裏的位置嗎?我覺得,正如你所說,有3個11.0的,2個13.0的......等等,就叫做MultiClass SVM? –