1. 程式人生 > >opencv答題卡識別 (一)

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

)(finish - start) ;

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,再呼叫識別函式。