#pragma once /******************************************************** * @file : error_api_define.h * @brief : 异常算法接口2的 公用的定义属性 * @details : * @author : qqm * @date : 2022.3.10 *********************************************************/ #include #include #include #include #include #include "public_define.h" #if defined(_MSC_VER) || defined(_WIN32) || defined(_WIN64) #define dll_export __declspec(dllexport) #define dll_import __declspec(dllimport) #else // __linux__ #define dll_export __attribute__ ((visibility("default"))) #include #endif #define MAX_SOCRE_DEFINE 1000 /////////////////////////////异常接口2返回的结构体设计//////////////////////////////// namespace eapi { /// 条码/二维码 struct ErCodeQ { preinfo::BOX_TYPE type; /// 类型 条码还是二维码 std::string result; /// 识别结果 preinfo::PaperRect box; /// 整个大的区域坐标 ErCodeQ() :type(preinfo::BOX_TYPE::BOX_EXAM_BARCODE), result("") {}; }; /// 填涂判断通用结果存放结构体 struct ErSinTt :preinfo::PaperRect { bool filled; /// 本填涂框是否是填涂 int fildedNumber; /// 本区域内有效的判断依据数量(红色点数) ErSinTt() :filled(false),fildedNumber(0) {}; }; /// 单个填涂序列(单个选择题,或者单个考号填涂列) struct ErTtRes { std::vector smallBoxes; int id; /// 题号 或 序号之类 int uuid; /// uuid ErTtRes() :id(0) { smallBoxes.clear(); }; }; /// 学号填涂框 struct ErFillNumber { bool effective; /// 是否有效 preinfo::PaperRect box; /// 整个大的区域坐标 std::string fillNumber; /// 填涂识别结果 std::vector smallItems; /// 每一列或行的填涂信息 ErFillNumber() :effective(false), fillNumber("") { smallItems.clear(); }; }; /// 选择题 可以考虑删除 struct ErChoise { std::vector sinChoise; /// 单个选择题 ErChoise() { sinChoise.clear(); }; }; /// Score区域 struct ErScore { bool effective; /// 是否有效 - 无效情况下 下面三个不需要读取 preinfo::SCORE_TYPE type; /// 打分框的类型 bool withHalf; /// 是否含有.5分 int limit; /// 上限分值 数据来自模板json中"limit"字段 double maxSocre; /// 小问最大分值 int cols; /// 个数 preinfo::PaperRect box; /// 打分框区域 std::vector smallBoxes; /// 单个打分框 std::vector vecSocreValue; /// 单个打分框内分数值 ErScore() :effective(true) { smallBoxes.clear(); vecSocreValue.clear(); }; double GetSocre() /// 获取该打分框分数 { double ret = 0.0; if (effective) { if ( smallBoxes.size() == 1) { //单个空,并且没有分数 if (maxSocre == -1) { //没有小问给选中最大分值,界面自己综合调整显示 ret = smallBoxes[0].fildedNumber > 0 ? MAX_SOCRE_DEFINE : 0; } else { //小问,给小问最大分 ret = smallBoxes[0].fildedNumber > 0 ? maxSocre : 0; } } else if (type == preinfo::SCORE_TYPE::NORMAL) { int selectred = -1; int maxred = 0; if (withHalf) { ret += smallBoxes[smallBoxes.size() - 1].fildedNumber > 0 ? 0.5 : 0; for (int m = 0; m < smallBoxes.size() - 1; m++) { if (maxred < smallBoxes[m].fildedNumber) { maxred = smallBoxes[m].fildedNumber; selectred = m; } } } else { for (int m = 0; m < smallBoxes.size(); m++) { if (maxred < smallBoxes[m].fildedNumber) { maxred = smallBoxes[m].fildedNumber; selectred = m; } } } if (selectred > -1) ret += vecSocreValue[selectred]; } else if (type == preinfo::SCORE_TYPE::COMBIN) { int selectred = -1; int maxred = 0; //十位 int tw = limit / 10; for (int m = 1; m <= tw; m++) { if (maxred < smallBoxes[m].fildedNumber) { maxred = smallBoxes[m].fildedNumber; selectred = m; } } if (selectred > -1) ret += 10 * vecSocreValue[selectred]; selectred = -1; maxred = 0; if (withHalf) { if (smallBoxes[smallBoxes.size() - 1].fildedNumber > 0) ret += 0.5; for (int m = tw + 1; m < smallBoxes.size() - 1; m++) { if (maxred < smallBoxes[m].fildedNumber) { maxred = smallBoxes[m].fildedNumber; selectred = m; } } } else { for (int m = tw + 1; m < smallBoxes.size(); m++) { if (maxred < smallBoxes[m].fildedNumber) { maxred = smallBoxes[m].fildedNumber; selectred = m; } } } if (selectred > -1) ret += vecSocreValue[selectred]; } else { int selectred = -1; int maxred = 0; for (int m = 0; m < smallBoxes.size(); m++) { if (maxred < smallBoxes[m].fildedNumber) { maxred = smallBoxes[m].fildedNumber; selectred = m; } } if (selectred > -1) ret += vecSocreValue[selectred]; } } else { ret = -1.0; } return ret; }; }; /// 通用主观题 struct ErBox { int id; /// 模板内的ID int uuid; /// 自增的UUID int multiple; /// 是否是多块 int orderNumber; /// 多块的块号 int marktype; /// markType preinfo::PaperRect box; /// 大区域 preinfo::BOX_TYPE type; /// 类型 ErScore score; /// 打分框 /// 选做题填涂框 选做题时候才有效 ErTtRes xzTt; /// 选做填涂 ErBox() :id(0), type(preinfo::BOX_TYPE::BOX_NONE) {}; }; /// 新增的异常处理接口交互结构体 typedef struct SingleErrorPaperInfo { /** 包含各种每一张答题卡上面的模板信息,坐标信息,题目信息,识别结果信息 */ int pageId; /// 本页页号 int status; /// 本页状态 std::string strPath; /// 矫正后图像绝对路径 ErFillNumber fillNumber; /// 填涂考号 std::vector codeResult; /// 条码/二维码识别结果 ErChoise choice; /// 选择题 std::vector boxes; /// 通用主观题 SingleErrorPaperInfo() :pageId(-1), status(PAPER_SUCC), strPath("") {}; }speinfo; }