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;
}