opencv答題卡識別 (一)
背景:答題卡閱卷需要游標閱讀機,有些小學校買不起游標閱讀機。
主要開源庫:opencv,版本3.0。
識別原理:把答題卡放在深色背景中,用查詢輪廓定位好答題卡位置,用透視變換取出答題卡影象,根據位置判斷是否被塗黑,識別出ABCD,對比標準答題計算出成績。
打包應用下載:
答題卡定位與識別程式碼先在windows下測試完成,然後通過NDK編譯讓android用JNI方式呼叫。
Windows下用圖片做測試源,主函式如下:
int main(intargc, char ** argv)
{
cvNamedWindow("test", CV_WINDOW_NORMAL);
unsignedcharresults[64 * 24];
intret = 0;
char* img_file = ".\\samples\\save.jpg";
IplImage* src = NULL; //源影象
src =cvLoadImage(img_file, 1);
if(!src){
printf("Couldn't load %s\n", img_file);
return0;
}
clock_tstart, finish;
doubleTotal_time;
start= clock();
ret =cv_omr(src, results);
finish= clock();
Total_time= (double
printf("%f ms\n", Total_time);
if(ret == 0)
printf("識別成功。\n");
if(ret == 1)
printf("答題卡四邊形定位失敗。\n");
if(ret == 2)
printf("行座標獲取失敗。\n");
return0;
}
其中int cv_omr(IplImage *img_src, unsignedchar *results);為測試程式與android應用都要使用的主要識別函式,unsignedchar *results為返回識別結果。
Android通過下面的函式來呼叫識別函式:
int Yuv420sp_omr(unsignedchar*results, unsignedchar* yuvdata, intwidth, int height)
{
intret = 0;
IplImage*image;
image= cvCreateImage(cvSize(width, height), IPL_DEPTH_8U, 3);
Yuv420sp2RGBimg(yuvdata,image, width, height);
//儲存影象到SD卡,觀察是否正確;win 下除錯
//cvSaveImage("/storage/emulated/0/save.jpg",image, 0);
//可以開始識別了,儲存測試圖片時不執行下面的程式碼
ret =cv_omr(image, results);
//結束,釋放影象
//cvReleaseImage(&image);
returnret;
}
此函式把Yuv420sp格式的影象資料轉換成IplImage,再呼叫識別函式。