123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223 |
- #pragma once
- /********************************************************
- * @file : error_api_define.h
- * @brief : 异常算法接口2的 公用的定义属性
- * @details :
- * @author : qqm
- * @date : 2022.3.10
- *********************************************************/
- #include <iostream>
- #include <string>
- #include <vector>
- #include <map>
- #include <unordered_map>
- #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 <memory>
- #endif
- #define MAX_SOCRE_DEFINE 1000
- /////////////////////////////异常接口2返回的结构体设计////////////////////////////////
- namespace eapi {
- /// 条码/二维码
- struct ErCodeQ {
- preinfo::BOX_TYPE type; /// 类型 条码还是二维码
- std::string result; /// 识别结果
- preinfo::PaperRect<double> box; /// 整个大的区域坐标
- ErCodeQ() :type(preinfo::BOX_TYPE::BOX_EXAM_BARCODE), result("") {};
- };
- /// 填涂判断通用结果存放结构体
- struct ErSinTt :preinfo::PaperRect<double> {
- bool filled; /// 本填涂框是否是填涂
- int fildedNumber; /// 本区域内有效的判断依据数量(红色点数)
- ErSinTt() :filled(false),fildedNumber(0) {};
- };
- /// 单个填涂序列(单个选择题,或者单个考号填涂列)
- struct ErTtRes {
- std::vector<ErSinTt> smallBoxes;
- int id; /// 题号 或 序号之类
- int uuid; /// uuid
- ErTtRes() :id(0) { smallBoxes.clear(); };
- };
- /// 学号填涂框
- struct ErFillNumber {
- bool effective; /// 是否有效
- preinfo::PaperRect<double> box; /// 整个大的区域坐标
- std::string fillNumber; /// 填涂识别结果
- std::vector<ErTtRes> smallItems; /// 每一列或行的填涂信息
- ErFillNumber() :effective(false), fillNumber("") { smallItems.clear(); };
- };
- /// 选择题 可以考虑删除
- struct ErChoise {
- std::vector<ErTtRes> 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<double> box; /// 打分框区域
- std::vector<ErSinTt> smallBoxes; /// 单个打分框
- std::vector<double> 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<double> 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<ErCodeQ> codeResult; /// 条码/二维码识别结果
- ErChoise choice; /// 选择题
- std::vector<ErBox> boxes; /// 通用主观题
- SingleErrorPaperInfo() :pageId(-1), status(PAPER_SUCC), strPath("") {};
- }speinfo;
- }
|