opencv 手寫選擇題閱卷 (二)字符識別
選擇題基本上只需要識別ABCD和空五個內容,理論上應該識別率比較高的,識別代碼參考了網上搜索的代碼,因為參考的網址比較多,現在也弄不清是參考何處的代碼了,在這裡就不一一感謝了.
基本步驟:
一,識別函數接受一般64X64的灰度圖像;
二,二值化並反色為黑底白字;
三,找出字符的最小包圍矩形,並大小歸一化為32X32;
四,計算圖像的HOG特征;
五,用SVM分類器對HOG特征進行識別,從而確定當前圖像屬於ABCD還是空白;
整個識別代碼還是比較簡單的.這得得益於opencv 對分類器的封裝,除了圖像預處理代碼,實際識別代碼只有幾行;
部分代碼
CvSVM svm; int svm_inited = 0; int svm_init(char * data_filename) { svm.load(data_filename);//"HOG_SVM_DATA.xml" svm_inited = 1; return 0; } // int svm_recognition(IplImage* image) { if (svm_inited != 1){ return -1; } //預處理 IplImage* test_img = cvCreateImage(cvSize(32, 32), 8, 1); preproc_img(image, test_img);//處理為黑底白字,並大小歸一化 #ifdef _WIN32 cvShowImage("Image", test_img); cvWaitKey(0); #endif //特征提取 HOGDescriptor *hog = new HOGDescriptor(cvSize(32, 32), cvSize(16, 16), cvSize(8, 8), cvSize(8, 8), 9); vector<float> descriptors;//存放結果 hog->compute(test_img, descriptors, Size(1, 1), Size(0, 0)); //Hog特征計算 cvReleaseImage(&test_img);//釋放不需要的圖像,釋放內存 //生成要檢測的特征數據矩陣 CvMat * mat_samples = cvCreateMat(1, descriptors.size(), CV_32FC1); int n = 0; for (vector<float>::iterator iter = descriptors.begin(); iter != descriptors.end(); iter++) { cvmSet(mat_samples, 0, n, *iter); n++; } //識別 int ret = svm.predict(mat_samples);//檢測結果 cvReleaseMat(&mat_samples); return ret; }