SchemaLoader.cpp 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452
  1. #include "StdAfx.h"
  2. #include "SchemaLoader.h"
  3. #include "..\EvaluationUtil\HttpClient.h"
  4. #include "..\ZLibWrapMemLib\UnZipFile.h"
  5. #include "..\Schema\schema_struct.h"
  6. #include "..\Identifier\schema_struct.h"
  7. #include <opencv2\opencv.hpp>
  8. #include <opencv2\xfeatures2d.hpp>
  9. #include "..\Schema\schema.h"
  10. #include "common.h"
  11. using namespace cv;
  12. using namespace schema;
  13. using namespace cv::xfeatures2d;
  14. CSchemaLoader::CSchemaLoader(void)
  15. {
  16. }
  17. CSchemaLoader::~CSchemaLoader(void)
  18. {
  19. }
  20. /*
  21. 初始化模板
  22. */
  23. void CSchemaLoader::SetPageDefault(identify::schema::ISCH_SCHEMA_PAGE& page)
  24. {
  25. //page.group_spacer =';';
  26. page.hei_du_ling_min_du =4;
  27. page.height =0;
  28. page.index =0;
  29. page.option_spacer =',';
  30. //page.unselect_char='*';
  31. page.width=0;
  32. }
  33. bool sort_string(ISCH_SCHEMA_CLIP x1, ISCH_SCHEMA_CLIP x2){
  34. if (atoi(x1.area_name_by_questionNo.c_str()) != atoi(x2.area_name_by_questionNo.c_str()))
  35. return atoi(x1.area_name_by_questionNo.c_str()) < atoi(x2.area_name_by_questionNo.c_str());
  36. else
  37. return x1.markUnitPart < x2.markUnitPart;
  38. }
  39. // 加载模板信息
  40. int CSchemaLoader::Load(std::string fileName, std::string muban_img_dir, schema::SCHEMA& schema_schema, boost::shared_ptr<const ISCH_Schema> & schema_identify, boost::shared_ptr<const HANDLE_INFO>& handleInfos)
  41. {
  42. boost::shared_ptr<HANDLE_INFO> handleInfos_0(new HANDLE_INFO);
  43. HANDLE_INFO & handleInfos_ = *handleInfos_0;
  44. CUnZipFile uzip(CString(fileName.c_str()));
  45. std::map<CString,std::vector<unsigned char>> map;
  46. while(uzip.HasMoreEntry()){
  47. CString fileNam;
  48. uzip.GetNextEntry(fileNam);
  49. char buffer[1024*8];
  50. int len;
  51. std::vector<unsigned char>& data =map[fileNam];
  52. data.reserve(1024*128);
  53. while((len = uzip.Read(buffer,1024*8))>0){
  54. if(data.capacity()<data.size()+len){
  55. int c=data.capacity()+1024*128;
  56. data.reserve(c);
  57. }
  58. int oldSize =data.size();
  59. data.resize(oldSize+len);
  60. char * dst =(char *)data.data()+oldSize;
  61. memcpy(dst,buffer,len);
  62. }
  63. }
  64. uzip.Close();
  65. std::map<CString,std::vector<unsigned char>>::iterator schemabytes= map.find(_T("schema.bytes"));
  66. if(schemabytes == map.end()){
  67. return SCH_LOAD_ERR_MISSINGFORMAT;
  68. }
  69. SCHEMA_VERSION version;
  70. std::vector<unsigned char>& data =schemabytes->second;
  71. serializor::SchemJsonSerializor::deserialize(std::string((char *)data.data(),data.size()),schema_schema,version);
  72. if(version!=CURRENT_SCHEMA_VERSTION)return SCH_LOAD_ERR_VERSIONCHANGE;
  73. if(schema_schema.state == 0) return SCH_LOAD_ERR_ZHUANGTAIBUZHENGQUE;
  74. boost::shared_ptr<ISCH_Schema> schema_identify_t(new ISCH_Schema);
  75. std::vector<identify::schema::ISCH_SCHEMA_PAGE>& schema_identify_ = *schema_identify_t;
  76. std::vector<schema::SCHEMA_QUESTION> &questions =schema_schema.questions;
  77. handleInfos_.resize(schema_schema.pages.size());
  78. schema_identify_.resize(schema_schema.pages.size());
  79. int j = 0;
  80. for (int idx_p=0;idx_p<schema_schema.pages.size();idx_p++)
  81. {
  82. PAGE_RESULT_HANDLE_INFO& handleInfo =handleInfos_[idx_p];
  83. schema::SCHEMA_PAGE& schema_page=schema_schema.pages[idx_p];
  84. /************************************************************************/
  85. /* 整理模板到结果中 */
  86. /************************************************************************/
  87. identify::schema::ISCH_SCHEMA_PAGE* page = &schema_identify_[idx_p];
  88. SetPageDefault(*page);
  89. page->index = idx_p;
  90. page->width =schema_page.width;
  91. page->height =schema_page.height;
  92. page->locatePoints.resize(schema_page.locatePoints.size());
  93. for (int idx_i = 0; idx_i < schema_page.locatePoints.size();idx_i++)
  94. {
  95. identify::schema::ISCH_SCHEMA_LOCATE_POINT& dst = page->locatePoints[idx_i];
  96. schema::SCHEMA_LOCATE_POINT& src = schema_page.locatePoints[idx_i];
  97. dst.centerx = src.centerx;
  98. dst.centery = src.centery;
  99. dst.width = src.width;
  100. dst.height = src.height;
  101. dst.nID = src.nID;
  102. }
  103. page->locateCrosses.resize(schema_page.locateCrosses.size());
  104. for (int idx_i = 0; idx_i < schema_page.locateCrosses.size(); idx_i++)
  105. {
  106. identify::schema::ISCH_SCHEMA_LOACTE_CROSS& dst = page->locateCrosses[idx_i];
  107. schema::SCHEMA_LOACTE_CROSS& src = schema_page.locateCrosses[idx_i];
  108. dst.centerx = src.centerx;
  109. dst.centery = src.centery;
  110. dst.width = src.width;
  111. dst.height = src.height;
  112. dst.nID = src.nID;
  113. dst.angle = src.angle;
  114. dst.sign = src.sign;
  115. }
  116. std::vector<identify::schema::ISCH_IDENTIFY_GROUP> groupsv;
  117. vector<identify::schema::ISCH_SCHEMA_ITEM> itemv;
  118. int nextItemId=1;
  119. handleInfo.page_index = schema_page.index;
  120. nextItemId = caulateGroupAndItem(schema_page.quekaobiaoji, nextItemId, itemv, groupsv, handleInfo.quekaoHandleInfo, GROUP_TYPE::QUEKAO);
  121. nextItemId = caulateGroupAndItem(schema_page.abjuanbjiaoji, nextItemId, itemv, groupsv, handleInfo.abjuanHandleInfo, GROUP_TYPE::NONE);
  122. nextItemId = caulateGroupAndItem(schema_page.tiantukaohao, nextItemId, itemv, groupsv, handleInfo.tiantukaohaoHandleInfo, GROUP_TYPE::TIANTUKAOHAO);
  123. nextItemId = caulateGroupAndItem2(schema_page.xuanzuoti, nextItemId, itemv, groupsv, handleInfo.xuanzuotiHandleInfo, GROUP_TYPE::XUANZUOTI);
  124. nextItemId = caulateGroupAndItem(schema_page.keguantiMatrix, nextItemId, itemv, groupsv, handleInfo.keguantiHandleInfo, GROUP_TYPE::KEGUANTI);
  125. std::map<int,schema::SCHEMA_QUESTION*> index_id_question;
  126. std::map<std::string, schema::SCHEMA_QUESTION*> index_questionCode_question;
  127. for (int idx_i=0;idx_i<questions.size();idx_i++)
  128. {
  129. index_id_question[questions[idx_i].nID]=&questions[idx_i];
  130. index_questionCode_question[questions[idx_i].question_code_new]=&questions[idx_i];
  131. }
  132. for (int idx_i = 0; idx_i<schema_page.keguantiMatrix.size(); idx_i++)
  133. {
  134. schema::SCHEMA_MATRIX_KEGUANTI& ke = schema_page.keguantiMatrix[idx_i];
  135. KEGUANTI_RESULT_HANDLE_INFO & khi = handleInfo.keguantiHandleInfo[idx_i];
  136. khi.group_question_count.resize(ke.group_count);
  137. khi.group_index.resize(ke.group_count);
  138. khi.question_code.resize(ke.question_count);
  139. for (int idx_g=0,idx_q=0;idx_g<ke.group_count;idx_g++)
  140. {
  141. khi.group_question_count[idx_g]=ke.group_size[idx_g];
  142. for (int idx_g_i=0;idx_g_i<ke.group_size[idx_g]&&idx_q<ke.question_count;idx_g_i++,idx_q++)
  143. {
  144. for (int k=0;k<questions.size();k++)
  145. {
  146. if(questions[k].nID == ke.question_ids[idx_q]){
  147. int group_index = khi.group_index[idx_g];
  148. khi.question_code[idx_q] = questions[k].question_code_new;
  149. switch (questions[k].questionType&schema::QTF_QUESTION_TYPE_MASK){
  150. //单选
  151. case schema::QuestionType::DANXUANTI:groupsv[group_index].omr_out_type = identify::schema::OMR_OUT_TYPE_SINGLE_STRICT; break;
  152. case schema::QuestionType::PANDUANTI:groupsv[group_index].omr_out_type = identify::schema::OMR_OUT_TYPE_SINGLE_STRICT; break;
  153. //多选
  154. case schema::QuestionType::DUOXUANTI:groupsv[group_index].omr_out_type = identify::schema::OMR_OUT_TYPE_MUTIL_STRICT; break;
  155. //主观题
  156. case schema::ZHUGUANTI:groupsv[group_index].omr_out_type = identify::schema::OMR_OUT_TYPE_SINGLE_STRICT; break;
  157. case schema::TIANKONGTI:groupsv[group_index].omr_out_type = identify::schema::OMR_OUT_TYPE_SINGLE_STRICT; break;
  158. }
  159. break;
  160. }
  161. }
  162. }
  163. }
  164. }
  165. for (int idx_i=0;idx_i<schema_page.xuanzuoti.size();idx_i++)
  166. {
  167. schema::SCHEMA_MATRIX_XUANZUOTI& ke = schema_page.xuanzuoti[idx_i];
  168. XUANZUOTI_RESULT_HANDLE_INFO & khi=handleInfo.xuanzuotiHandleInfo[idx_i];
  169. khi.mark_unit.resize(khi.group_index.size());
  170. khi.mark_unit_question_code.resize(khi.group_index.size());
  171. khi.option_question_code.resize(khi.group_index.size());
  172. khi.xuantishu.resize(khi.group_index.size());
  173. for (int idx=0;idx<khi.group_index.size();idx++)
  174. {
  175. if(ke.xuantishu==1){
  176. groupsv[khi.group_index[idx]].omr_out_type = identify::schema::OMR_OUT_TYPE_SINGLE_NONSTRICT;
  177. }else{
  178. groupsv[khi.group_index[idx]].omr_out_type = identify::schema::OMR_OUT_TYPE_MUTIL_STRICT;
  179. }
  180. }
  181. vector<string> questions1;
  182. split(ke.outputcharsnew, (string)";", &questions1);
  183. for (int index_group=0;index_group<khi.group_index.size();index_group++)
  184. {
  185. khi.option_question_code[index_group].resize(questions1.size());
  186. khi.xuantishu[index_group]=ke.xuantishu;
  187. for (int index1=0;index1<questions1.size();index1++)
  188. {
  189. vector<string> questions2;
  190. split(questions1[index1],(string)",",&questions2);
  191. khi.option_question_code[index_group][index1]=questions2;
  192. for (int index2=0;index2<questions2.size();index2++)
  193. {
  194. if(index_questionCode_question.find(questions2[index2])!=index_questionCode_question.end()){
  195. std::vector<std::string>& markunit=khi.mark_unit[index_group];
  196. schema::SCHEMA_QUESTION * question = index_questionCode_question[questions2[index2]];
  197. int markunit_index =-1;
  198. char szmarkunit[32];
  199. sprintf_s(szmarkunit,"%d",question->nMarkUnit);
  200. for (int index_markunit=0;index_markunit<markunit.size();index_markunit++)
  201. {
  202. if(markunit[index_markunit] ==szmarkunit){
  203. markunit_index=index_markunit;
  204. break;
  205. }
  206. }
  207. if(markunit_index<0){
  208. markunit.push_back(szmarkunit);
  209. khi.mark_unit_question_code[index_group].push_back(question->question_code_new);
  210. }else{
  211. khi.mark_unit_question_code[index_group][markunit_index].append(",");
  212. khi.mark_unit_question_code[index_group][markunit_index].append(question->question_code_new);
  213. }
  214. }
  215. }
  216. }
  217. }
  218. }
  219. page->codes.resize(schema_page.codes.size());
  220. for (int idx_i = 0; idx_i < schema_page.codes.size(); idx_i++)
  221. {
  222. identify::schema::ISCH_SCHEMA_CODE& dst = page->codes[idx_i];
  223. schema::SCHEMA_CODE& src = schema_page.codes[idx_i];
  224. dst.centerx = src.centerx;
  225. dst.centery = src.centery;
  226. dst.width = src.width;
  227. dst.height = src.height;
  228. dst.nID = src.nID;
  229. dst.bDirection = (identify::schema::ISCH_DIRECTION)(int)src.bDirection;
  230. }
  231. page->groups=groupsv;
  232. page->items=itemv;
  233. page->cutAreas.resize(schema_page.clips.size() + schema_page.clips2.size());
  234. int nClips2 = 0;
  235. for (int idx_i = 0; idx_i < schema_page.clips2.size(); idx_i++)
  236. {
  237. identify::schema::ISCH_SCHEMA_CLIP& dst = page->cutAreas[idx_i];
  238. schema::SCHEMA_CLIP& src = schema_page.clips2[idx_i];
  239. dst.centerx = src.centerx;
  240. dst.centery = src.centery;
  241. dst.width = src.width;
  242. dst.height = src.height;
  243. dst.nID = src.nID;
  244. dst.area_name = src.area_name;
  245. dst.area_name_by_questionNo = src.area_name_by_questionNoNew;
  246. dst.markUnit = src.markUnit;
  247. dst.markUnitPart = src.markUnitPart;
  248. nClips2++;
  249. }
  250. for (int idx_i = 0; idx_i < schema_page.clips.size(); idx_i++)
  251. {
  252. identify::schema::ISCH_SCHEMA_CLIP& dst = page->cutAreas[idx_i + nClips2];
  253. schema::SCHEMA_CLIP& src = schema_page.clips[idx_i];
  254. dst.centerx = src.centerx;
  255. dst.centery = src.centery;
  256. dst.width = src.width;
  257. dst.height = src.height;
  258. dst.nID = src.nID;
  259. dst.area_name = src.area_name;
  260. dst.area_name_by_questionNo = src.area_name_by_questionNoNew;
  261. dst.markUnit = src.markUnit;
  262. dst.markUnitPart = src.markUnitPart;
  263. }
  264. std::sort(page->cutAreas.begin(), page->cutAreas.end(), sort_string);
  265. CString imgName ;
  266. imgName.Format(_T("%05d.jpg"),schema_page.nID);
  267. vector<uchar> & fff =map[imgName];
  268. Mat img = imdecode(fff,CV_LOAD_IMAGE_GRAYSCALE);
  269. double angle =schema_page.angle;
  270. double a = fmod(fmod(angle,360)+360,360);
  271. int nWidth,nHeight;
  272. if((a>45&&a<=135)||(a>45+180&&a<=135+180)){
  273. nHeight = img.cols;
  274. nWidth = img.rows;
  275. }else{
  276. nWidth = img.cols;
  277. nHeight = img.rows;
  278. }
  279. page->width = nWidth;
  280. page->height = nHeight;
  281. double sina = sin(CV_PI*angle/180);
  282. double cosa = cos(CV_PI*angle/180);
  283. CvPoint2D32f center0 = cvPoint2D32f(img.cols/2.0,img.rows/2.0);
  284. CvPoint2D32f center1 = cvPoint2D32f(nWidth/2.0,nHeight/2.0);
  285. float offsetx = center1.x - (cosa*center0.x+sina*center0.y);
  286. float offsety = center1.y - (-sina*center0.x+cosa*center0.y);
  287. float data[6]={cosa,sina,offsetx,-sina,cosa,offsety};
  288. Mat m(2,3,CV_32F,data);
  289. Mat img_rotated;
  290. warpAffine(img,img_rotated,m,cvSize(nWidth,nHeight));
  291. CString imgFileName;
  292. char imgfilename_a [1024];
  293. imgFileName.Format(_T("%s\\%05d_original.jpg"),CString(muban_img_dir.c_str()),idx_p);
  294. WideCharToMultiByte(CP_ACP,0,imgFileName,-1,imgfilename_a,1024,NULL,NULL);
  295. imwrite(imgfilename_a,img);
  296. imgFileName.Format(_T("%s\\%05d.jpg"), CString(muban_img_dir.c_str()), idx_p);
  297. WideCharToMultiByte(CP_ACP,0,imgFileName,-1,imgfilename_a,1024,NULL,NULL);
  298. imwrite(imgfilename_a,img_rotated);
  299. img.release();
  300. IplImage * img_smoothd = &IplImage(img_rotated);
  301. cvSmooth(img_smoothd, img_smoothd, CV_GAUSSIAN, 5);
  302. caculateLocateArea(img_rotated,schema_page.locateAreas,page->locateAreas);
  303. std::vector<identify::schema::ISCH_IDENTIFY_AREA>& assistLocateArea = page->assistLocateArea;
  304. caculateLocateArea(img_rotated,schema_page.quekaobiaoji,assistLocateArea);
  305. caculateLocateArea(img_rotated,schema_page.abjuanbjiaoji,assistLocateArea);
  306. caculateLocateArea(img_rotated,schema_page.tiantukaohao,assistLocateArea);
  307. caculateLocateArea(img_rotated,schema_page.keguantiMatrix,assistLocateArea);
  308. caculateLocateArea(img_rotated,schema_page.xuanzuoti,assistLocateArea);
  309. }
  310. schema_identify = schema_identify_t;
  311. handleInfos = handleInfos_0;
  312. return SCH_LOAD_SUCCESS;
  313. }
  314. //选做题
  315. template<class T, class T2> int CSchemaLoader::caulateGroupAndItem2(std::vector<T> &matrix, int nextItemId, vector<identify::schema::ISCH_SCHEMA_ITEM> &itemv, std::vector<identify::schema::ISCH_IDENTIFY_GROUP> &groupsv, std::vector<T2>& handleInfos, GROUP_TYPE _type)
  316. {
  317. for (int i=0;i<matrix.size();i++)
  318. {
  319. T2 hi;
  320. T& k = matrix[i];
  321. std::vector<std::string> answers;
  322. split((std::string)k.outputcharsnew,(std::string)";",&answers);
  323. if (k.direction == schema::Horizontal){
  324. for (int m=0;m<k.nRows;m++)
  325. {
  326. hi.group_index.push_back(groupsv.size());
  327. identify::schema::ISCH_IDENTIFY_GROUP group;
  328. group.itemCount = k.nCols;
  329. group.omr_out_type = identify::schema::OMR_OUT_TYPE_SINGLE_STRICT;
  330. group.group_type = _type;
  331. for (int n=0;n<k.nCols;n++)
  332. {
  333. identify::schema::ISCH_SCHEMA_ITEM item;
  334. double hGap = k.nCols>1?(k.width-(k.optionWidth*k.nCols))/(k.nCols-1):0;
  335. double vGap = k.nRows>1?(k.height-(k.optionHeight*k.nRows))/(k.nRows-1):0;
  336. item.centerx = (k.centerx-k.width/2)+n*(k.width+hGap)/k.nCols+k.optionWidth/2.0;
  337. item.centery = (k.centery-k.height/2)+m*(k.height+vGap)/k.nRows+k.optionHeight/2.0;
  338. item.width = k.optionWidth;
  339. item.height = k.optionHeight;
  340. item.nID = nextItemId++;
  341. strcpy_s(item.OutChar,answers[n].c_str());
  342. group.itemIndex.push_back(itemv.size());
  343. itemv.push_back(item);
  344. }
  345. groupsv.push_back(group);
  346. }
  347. }else{
  348. for (int n=0;n<k.nCols;n++)
  349. {
  350. hi.group_index.push_back(groupsv.size());
  351. identify::schema::ISCH_IDENTIFY_GROUP group;
  352. group.itemCount = k.nRows;
  353. group.omr_out_type = identify::schema::OMR_OUT_TYPE_SINGLE_STRICT;
  354. for (int m=0;m<k.nRows;m++)
  355. {
  356. identify::schema::ISCH_SCHEMA_ITEM item;
  357. double hGap = k.nCols>1?(k.width-(k.optionWidth*k.nCols))/(k.nCols-1):0;
  358. double vGap = k.nRows>1?(k.height-(k.optionHeight*k.nRows))/(k.nRows-1):0;
  359. item.centerx = (k.centerx-k.width/2)+n*(k.width+hGap)/k.nCols+k.optionWidth/2.0;
  360. item.centery = (k.centery-k.height/2)+m*(k.height+vGap)/k.nRows+k.optionHeight/2.0;
  361. item.width = k.optionWidth;
  362. item.height = k.optionHeight;
  363. item.nID = nextItemId++;
  364. strcpy_s(item.OutChar,answers[m].c_str());
  365. group.itemIndex.push_back(itemv.size());
  366. itemv.push_back(item);
  367. }
  368. groupsv.push_back(group);
  369. }
  370. }
  371. handleInfos.push_back(hi);
  372. }
  373. return nextItemId;
  374. }
  375. template<class T, class T2> int CSchemaLoader::caulateGroupAndItem(std::vector<T> &matrix, int nextItemId, vector<identify::schema::ISCH_SCHEMA_ITEM> &itemv, std::vector<identify::schema::ISCH_IDENTIFY_GROUP> &groupsv,
  376. std::vector<T2>& handleInfos, GROUP_TYPE _type)
  377. {
  378. for (int i=0;i<matrix.size();i++)
  379. {
  380. T2 hi;
  381. T& k = matrix[i];
  382. std::vector<std::string> answers;
  383. split((std::string)k.outputchars,(std::string)",",&answers);
  384. if(k.direction == schema::Horizontal){
  385. for (int m=0;m<k.nRows;m++)
  386. {
  387. hi.group_index.push_back(groupsv.size());
  388. identify::schema::ISCH_IDENTIFY_GROUP group;
  389. group.group_type = _type;
  390. group.itemCount = k.nCols;
  391. group.omr_out_type = identify::schema::OMR_OUT_TYPE_SINGLE_STRICT;
  392. for (int n=0;n<k.nCols;n++)
  393. {
  394. identify::schema::ISCH_SCHEMA_ITEM item;
  395. double hGap = k.nCols>1?(k.width-(k.optionWidth*k.nCols))/(k.nCols-1):0;
  396. double vGap = k.nRows>1?(k.height-(k.optionHeight*k.nRows))/(k.nRows-1):0;
  397. item.centerx = (k.centerx-k.width/2)+n*(k.width+hGap)/k.nCols+k.optionWidth/2.0;
  398. item.centery = (k.centery-k.height/2)+m*(k.height+vGap)/k.nRows+k.optionHeight/2.0;
  399. item.width = k.optionWidth;
  400. item.height = k.optionHeight;
  401. item.nID = nextItemId++;
  402. strcpy_s(item.OutChar,answers[n].c_str());
  403. group.itemIndex.push_back(itemv.size());
  404. itemv.push_back(item);
  405. }
  406. groupsv.push_back(group);
  407. }
  408. }else{
  409. for (int n=0;n<k.nCols;n++)
  410. {
  411. hi.group_index.push_back(groupsv.size());
  412. identify::schema::ISCH_IDENTIFY_GROUP group;
  413. group.group_type = _type;
  414. group.itemCount = k.nRows;
  415. group.omr_out_type = identify::schema::OMR_OUT_TYPE_SINGLE_STRICT;
  416. for (int m=0;m<k.nRows;m++)
  417. {
  418. identify::schema::ISCH_SCHEMA_ITEM item;
  419. double hGap = k.nCols>1?(k.width-(k.optionWidth*k.nCols))/(k.nCols-1):0;
  420. double vGap = k.nRows>1?(k.height-(k.optionHeight*k.nRows))/(k.nRows-1):0;
  421. item.centerx = (k.centerx-k.width/2)+n*(k.width+hGap)/k.nCols+k.optionWidth/2.0;
  422. item.centery = (k.centery-k.height/2)+m*(k.height+vGap)/k.nRows+k.optionHeight/2.0;
  423. item.width = k.optionWidth;
  424. item.height = k.optionHeight;
  425. item.nID = nextItemId++;
  426. strcpy_s(item.OutChar,answers[m].c_str());
  427. group.itemIndex.push_back(itemv.size());
  428. itemv.push_back(item);
  429. }
  430. groupsv.push_back(group);
  431. }
  432. }
  433. handleInfos.push_back(hi);
  434. }
  435. return nextItemId;
  436. }