error_api_define.h 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223
  1. #pragma once
  2. /********************************************************
  3. * @file : error_api_define.h
  4. * @brief : 异常算法接口2的 公用的定义属性
  5. * @details :
  6. * @author : qqm
  7. * @date : 2022.3.10
  8. *********************************************************/
  9. #include <iostream>
  10. #include <string>
  11. #include <vector>
  12. #include <map>
  13. #include <unordered_map>
  14. #include "public_define.h"
  15. #if defined(_MSC_VER) || defined(_WIN32) || defined(_WIN64)
  16. #define dll_export __declspec(dllexport)
  17. #define dll_import __declspec(dllimport)
  18. #else // __linux__
  19. #define dll_export __attribute__ ((visibility("default")))
  20. #include <memory>
  21. #endif
  22. #define MAX_SOCRE_DEFINE 1000
  23. /////////////////////////////异常接口2返回的结构体设计////////////////////////////////
  24. namespace eapi {
  25. /// 条码/二维码
  26. struct ErCodeQ {
  27. preinfo::BOX_TYPE type; /// 类型 条码还是二维码
  28. std::string result; /// 识别结果
  29. preinfo::PaperRect<double> box; /// 整个大的区域坐标
  30. ErCodeQ() :type(preinfo::BOX_TYPE::BOX_EXAM_BARCODE), result("") {};
  31. };
  32. /// 填涂判断通用结果存放结构体
  33. struct ErSinTt :preinfo::PaperRect<double> {
  34. bool filled; /// 本填涂框是否是填涂
  35. int fildedNumber; /// 本区域内有效的判断依据数量(红色点数)
  36. ErSinTt() :filled(false),fildedNumber(0) {};
  37. };
  38. /// 单个填涂序列(单个选择题,或者单个考号填涂列)
  39. struct ErTtRes {
  40. std::vector<ErSinTt> smallBoxes;
  41. int id; /// 题号 或 序号之类
  42. int uuid; /// uuid
  43. ErTtRes() :id(0) { smallBoxes.clear(); };
  44. };
  45. /// 学号填涂框
  46. struct ErFillNumber {
  47. bool effective; /// 是否有效
  48. preinfo::PaperRect<double> box; /// 整个大的区域坐标
  49. std::string fillNumber; /// 填涂识别结果
  50. std::vector<ErTtRes> smallItems; /// 每一列或行的填涂信息
  51. ErFillNumber() :effective(false), fillNumber("") { smallItems.clear(); };
  52. };
  53. /// 选择题 可以考虑删除
  54. struct ErChoise {
  55. std::vector<ErTtRes> sinChoise; /// 单个选择题
  56. ErChoise() { sinChoise.clear(); };
  57. };
  58. /// Score区域
  59. struct ErScore {
  60. bool effective; /// 是否有效 - 无效情况下 下面三个不需要读取
  61. preinfo::SCORE_TYPE type; /// 打分框的类型
  62. bool withHalf; /// 是否含有.5分
  63. int limit; /// 上限分值 数据来自模板json中"limit"字段
  64. double maxSocre; /// 小问最大分值
  65. int cols; /// 个数
  66. preinfo::PaperRect<double> box; /// 打分框区域
  67. std::vector<ErSinTt> smallBoxes; /// 单个打分框
  68. std::vector<double> vecSocreValue; /// 单个打分框内分数值
  69. ErScore() :effective(true) { smallBoxes.clear(); vecSocreValue.clear(); };
  70. double GetSocre() /// 获取该打分框分数
  71. {
  72. double ret = 0.0;
  73. if (effective)
  74. {
  75. if ( smallBoxes.size() == 1)
  76. {
  77. //单个空,并且没有分数
  78. if (maxSocre == -1)
  79. {
  80. //没有小问给选中最大分值,界面自己综合调整显示
  81. ret = smallBoxes[0].fildedNumber > 0 ? MAX_SOCRE_DEFINE : 0;
  82. }
  83. else
  84. {
  85. //小问,给小问最大分
  86. ret = smallBoxes[0].fildedNumber > 0 ? maxSocre : 0;
  87. }
  88. }
  89. else if (type == preinfo::SCORE_TYPE::NORMAL)
  90. {
  91. int selectred = -1;
  92. int maxred = 0;
  93. if (withHalf)
  94. {
  95. ret += smallBoxes[smallBoxes.size() - 1].fildedNumber > 0 ? 0.5 : 0;
  96. for (int m = 0; m < smallBoxes.size() - 1; m++)
  97. {
  98. if (maxred < smallBoxes[m].fildedNumber)
  99. {
  100. maxred = smallBoxes[m].fildedNumber;
  101. selectred = m;
  102. }
  103. }
  104. }
  105. else
  106. {
  107. for (int m = 0; m < smallBoxes.size(); m++)
  108. {
  109. if (maxred < smallBoxes[m].fildedNumber)
  110. {
  111. maxred = smallBoxes[m].fildedNumber;
  112. selectred = m;
  113. }
  114. }
  115. }
  116. if (selectred > -1)
  117. ret += vecSocreValue[selectred];
  118. }
  119. else if (type == preinfo::SCORE_TYPE::COMBIN)
  120. {
  121. int selectred = -1;
  122. int maxred = 0;
  123. //十位
  124. int tw = limit / 10;
  125. for (int m = 1; m <= tw; m++)
  126. {
  127. if (maxred < smallBoxes[m].fildedNumber)
  128. {
  129. maxred = smallBoxes[m].fildedNumber;
  130. selectred = m;
  131. }
  132. }
  133. if (selectred > -1)
  134. ret += 10 * vecSocreValue[selectred];
  135. selectred = -1;
  136. maxred = 0;
  137. if (withHalf)
  138. {
  139. if (smallBoxes[smallBoxes.size() - 1].fildedNumber > 0)
  140. ret += 0.5;
  141. for (int m = tw + 1; m < smallBoxes.size() - 1; m++)
  142. {
  143. if (maxred < smallBoxes[m].fildedNumber)
  144. {
  145. maxred = smallBoxes[m].fildedNumber;
  146. selectred = m;
  147. }
  148. }
  149. }
  150. else
  151. {
  152. for (int m = tw + 1; m < smallBoxes.size(); m++)
  153. {
  154. if (maxred < smallBoxes[m].fildedNumber)
  155. {
  156. maxred = smallBoxes[m].fildedNumber;
  157. selectred = m;
  158. }
  159. }
  160. }
  161. if (selectred > -1)
  162. ret += vecSocreValue[selectred];
  163. }
  164. else
  165. {
  166. int selectred = -1;
  167. int maxred = 0;
  168. for (int m = 0; m < smallBoxes.size(); m++)
  169. {
  170. if (maxred < smallBoxes[m].fildedNumber)
  171. {
  172. maxred = smallBoxes[m].fildedNumber;
  173. selectred = m;
  174. }
  175. }
  176. if (selectred > -1)
  177. ret += vecSocreValue[selectred];
  178. }
  179. }
  180. else
  181. {
  182. ret = -1.0;
  183. }
  184. return ret;
  185. };
  186. };
  187. /// 通用主观题
  188. struct ErBox {
  189. int id; /// 模板内的ID
  190. int uuid; /// 自增的UUID
  191. int multiple; /// 是否是多块
  192. int orderNumber; /// 多块的块号
  193. int marktype; /// markType
  194. preinfo::PaperRect<double> box; /// 大区域
  195. preinfo::BOX_TYPE type; /// 类型
  196. ErScore score; /// 打分框
  197. /// 选做题填涂框 选做题时候才有效
  198. ErTtRes xzTt; /// 选做填涂
  199. ErBox() :id(0), type(preinfo::BOX_TYPE::BOX_NONE) {};
  200. };
  201. /// 新增的异常处理接口交互结构体
  202. typedef struct SingleErrorPaperInfo
  203. {
  204. /**
  205. 包含各种每一张答题卡上面的模板信息,坐标信息,题目信息,识别结果信息
  206. */
  207. int pageId; /// 本页页号
  208. int status; /// 本页状态
  209. std::string strPath; /// 矫正后图像绝对路径
  210. ErFillNumber fillNumber; /// 填涂考号
  211. std::vector<ErCodeQ> codeResult; /// 条码/二维码识别结果
  212. ErChoise choice; /// 选择题
  213. std::vector<ErBox> boxes; /// 通用主观题
  214. SingleErrorPaperInfo() :pageId(-1), status(PAPER_SUCC), strPath("") {};
  215. }speinfo;
  216. }