123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446 |
- #pragma once
- #include <string>
- #include <opencv2/opencv.hpp>
- #include <vector>
- using namespace cv;
- using namespace std;
- namespace identify{
- namespace {
- enum OMR_QUESTION_TYPE{
- DANXUANTI,
- DUOXUANTI,
- TIANKONGTI,
- ZHUTUANTI,
- TIANKONGTI2,// 带分数
- XUANZUOTI, // 选做题
- DUOXUANTIEX, // 不定项
- };
- }
- namespace analysis{
- struct SAMPLE_KEGUANTITUDIAN{
- //涂黑相对面积
- float BlackRefArea;
- //黑色区域高黑度相对面积
- float HighBlackRefArea;
- //黑色区域低黑度相对面积
- float LowBlackRefArea;
- //模糊度
- float Blur;
- //涂黑区域平均灰度
- float RefAvgGray;
- //当前组的最大涂黑相对面积
- float MaxBlackRefArea;
- //当前组的最小涂黑相对面积
- float MinBlackRefArea;
- //同组最大高黑度区域相对面积
- float MaxHighBlackRefArea;
- //同组最小平均灰度
- float MinRefAvgGray;
- };
- /*匹配结果*/
- struct MATCH_REUSLT{
- MATCH_REUSLT(){ matched = false; matched_count = 0; total_count = 0; schema_index = -1; scale = -1; dir = 0; }
- bool matched;
- int matched_count;
- int total_count;
- int schema_index;
- double scale;
- int dir;
- double transfrom[6];
- };
- }
- namespace schema{
- //旋转角 枚举各旋转角(逆时针旋转 0度,90度,180度,270度)
- enum ISCH_ROTATION{
- //逆时针旋转 0度
- ROTATION_0 = 1,
- //逆时针旋转 90度
- ROTATION_90 = 2,
- //逆时针旋转 180度
- ROTATION_180 = 4,
- //逆时针旋转 270度
- ROTATION_270 = 8
- };
- //方向标记
- enum ISCH_DIR_FLAG{
- DIR_FLAG_UP = 1,
- DIR_FLAG_DOWN = 2,
- DIR_FLAG_LEFT = 4,
- DIR_FLAG_RIGHT = 8
- };
- template<typename T>struct ISCH_SCHEMA_RECT_FIELD{
- T centerx;
- T centery;
- T width;
- T height;
- };
- struct ISCH_SCHEMA_ELEMENT_FIELD :ISCH_SCHEMA_RECT_FIELD<float>{
- int nID;
- };
- struct ISCH_SCHEMA_LOCATE_POINT :ISCH_SCHEMA_ELEMENT_FIELD{//定位点
- };
- struct ISCH_SCHEMA_LOCATE_AREA :ISCH_SCHEMA_ELEMENT_FIELD{//区域定位点
- };
- enum ISCH_SCHEMA_CROSS_SIGN_FLAG{
- //表示向上的边
- ISCH_SCHEMA_CROSS_SIGN_UP = 1,
- //表示向下的边
- ISCH_SCHEMA_CROSS_SIGN_DOWN = 2,
- //表示向左的边
- ISCH_SCHEMA_CROSS_SIGN_LEFT = 4,
- //表示向右的边
- ISCH_SCHEMA_CROSS_SIGN_RIGHT = 8,
- };
- struct ISCH_SCHEMA_LOACTE_CROSS :ISCH_SCHEMA_ELEMENT_FIELD{//交叉点定位
- int sign;
- double angle;
- };
- enum ISCH_DIRECTION{
- Horizontal,
- Vertical,
- DIR_UNKNOWN,
- };
- struct ISCH_SCHEMA_CODE :ISCH_SCHEMA_ELEMENT_FIELD{//条码、二维码
- ISCH_DIRECTION bDirection;
- };
- struct ISCH_SCHEMA_ITEM :ISCH_SCHEMA_ELEMENT_FIELD{//填涂项
- //填涂项输出字符
- char OutChar[128];
- int nGroupID;
- int nMatrixID;
- int keguanti_question_locate_point_index;
- };
- enum ISCH_OUT_TYPE_FLAG{
- OTF_SINGLE = 1,
- OTF_MUTIL = 1 << 1,
- OTF_STRICT = 1 << 3,
- OTF_NONSTRICT = 1 << 4,
- OTF_NONSTRICT_ERROR = 1 << 5,
- };
- //客观题输出类型
- enum ISCH_OMR_OUT_TYPE{
- // 输出一个或*号,若解析中有0个、2个或2个以上涂点被填涂,输出*号
- OMR_OUT_TYPE_SINGLE_NONSTRICT_ERROR = OTF_SINGLE | OTF_NONSTRICT_ERROR,
- // 输出一个,若解析中有2个或2个以上涂点被填涂,则从中选出一个作为该组结果
- OMR_OUT_TYPE_SINGLE_NONSTRICT = OTF_SINGLE | OTF_NONSTRICT,
- // 输出一个,若解析中有2个或2个以上涂点被填涂,则认为用户多选,输出多选字符
- OMR_OUT_TYPE_SINGLE_STRICT = OTF_SINGLE | OTF_STRICT,
- // 输出多选字符
- OMR_OUT_TYPE_MUTIL_STRICT = OTF_MUTIL | OTF_STRICT,
- };
- struct ISCH_QUESTION_BASIC{
- std::string question_code;
- int question_index;
- };
- enum ISCH_QUESTION_TYPE_FLAG{
- //单选题
- QTF_DANXUANTI = 1,
- //多选
- QTF_DUOXUANTI = 2,
- //判断题
- QTF_PANDUANTI = 3,
- //填空题
- QTF_TIANKONGTI = 4,
- //主观题
- QTF_ZHUGUANTI = 5,
- //是否是选做题标记位
- QTF_XUANZUOTI = 0x100,
- //是否是客观题标记为
- QTF_XUANZE = 0x200,
- //题型蒙版
- QTF_QUESTION_TYPE_MASK = 0xff,
- };
- struct ISCH_SCHEMA_GROUP :ISCH_SCHEMA_ELEMENT_FIELD{//填涂组
- //本组涂点涂点数量
- int itemCount;
- int nMatrixID;
- //OMR 输出类型
- ISCH_OMR_OUT_TYPE omr_out_type;
- };
- struct ISCH_SCHEMA_CLIP :ISCH_SCHEMA_ELEMENT_FIELD{//切割区域
- //裁切区域名称
- std::string area_name;
- int markUnit;
- //该区域对应的切块的第几块(从1开始)
- int markUnitPart;
- std::string area_name_by_questionNo;
- };
- enum class GROUP_TYPE
- {
- NONE,
- TIANTUKAOHAO,
- KEGUANTI,
- QUEKAO,
- XUANZUOTI,
- };
- struct ISCH_IDENTIFY_GROUP :ISCH_SCHEMA_GROUP{
- std::vector<int> itemIndex;
- GROUP_TYPE group_type;
- };
- struct ISCH_IDENTIFY_AREA{
- ISCH_SCHEMA_LOCATE_AREA locate_area;
- std::vector<KeyPoint> locateAreasKeyPoints;
- cv::Mat locateAreasDescriptor;
- CvPoint locateAreasOffset;
- };
- struct ISCH_SCHEMA_ZHUGUANTI :ISCH_SCHEMA_ELEMENT_FIELD, ISCH_QUESTION_BASIC{//题目分数
- std::vector<ISCH_SCHEMA_ELEMENT_FIELD> options;
- //有效评分框数量(题目总分较小,无需所有评分框)
- int valid_option_count;
- };
- struct ISCH_SCHEMA_TIANKONGTI :ISCH_SCHEMA_ELEMENT_FIELD, ISCH_QUESTION_BASIC{//题目分数
- ISCH_SCHEMA_ELEMENT_FIELD option;
- };
- class ISCH_SCHEMA_PAGE{
- public:
- ISCH_SCHEMA_PAGE(){
- index = -1;
- option_spacer = ',';
- hei_du_ling_min_du = 4;
- width = -1;
- height = -1;
- }
- //从0开始的试卷页码序号
- int index;
- //模板图像宽度
- int width;
- //模板图像高度
- int height;
- std::vector<ISCH_SCHEMA_LOCATE_POINT> locatePoints;
- std::vector<ISCH_SCHEMA_LOACTE_CROSS> locateCrosses;
- std::vector<ISCH_IDENTIFY_AREA> locateAreas;
- std::vector<ISCH_IDENTIFY_AREA> assistLocateArea;
- std::vector<ISCH_SCHEMA_CODE> codes;
- std::vector<ISCH_IDENTIFY_GROUP> groups;
- std::vector<ISCH_SCHEMA_ITEM> items;
- std::vector<ISCH_SCHEMA_CLIP> cutAreas;
- std::vector<ISCH_SCHEMA_TIANKONGTI> tiankongtis;
- std::vector<ISCH_SCHEMA_ZHUGUANTI> zhuguantis;
- //多个选项之间的间隔字符
- char option_spacer;
- //黑度灵敏度
- int hei_du_ling_min_du;
- };
- typedef std::vector<ISCH_SCHEMA_PAGE> ISCH_Schema;
- }
- namespace result{
- //识别结果
- enum IDENDTIFY_RESULT{
- //成功
- IDF_SUCCESS,
- //失败
- IDF_FAILURE,
- //创建模板--失败
- IDF_TEMPLATE_FAILURE,
- //创建模板--没有找到足够的定位点
- IDF_TEMPLATE_NOTFOUND_ENOUGH_LOCATEPOINT,
- //创建模板--无法找到内容结束位置
- IDF_TEMPLATE_NOTFOUNDBOTTOM,
- //创建模板--试卷二维码非法
- IDF_TEMPLATE_QRCODE_ILLEGAL,
- //无法添加模板,模板已被锁定,不能再增加
- IDF_TEMPLATE_LOCKED,
- //无法添加模板,模板重复
- IDF_TEMPLATE_REPEAT,
- //没有找到足够的定位点
- IDF_NOTFOUND_ENOUGH_LOCATEPOINT,
- //无法匹配模板
- IDF_CANNOT_MATCH_TEMPLATE,
- //二维码解析失败
- IDF_PRASE_QR_ERROR,
- //没有模板
- IDF_MISSING_TEMPLATES,
- //图像太小
- IDF_SIZE2SMALL,
- //边长比例与模板不符
- IDF_SIDERATIO,
- //除数为零
- IDF_DIVIDE_ZERO,
- ERR_MEM_UNENOUGH,
- };
- enum OMR_QUESTION_STATE{
- //正常
- OMR_QUESTION_STATE_NORMAL,
- //多涂
- OMR_QUESTION_STATE_DUOTU,
- //漏涂
- OMR_QUESTION_STATE_LOUTU,
- //漏批
- OMR_QUESTION_STATE_LOUPI,
- //无法识别
- OMR_QUESTION_STATE_WUFASHIBIE
- };
- //对象结果(基础结构体)
- struct OBJ_RESULT{
- unsigned int obj_id;//对象ID
- };
- //对象位置区域描述
- template<class T> struct OBJ_RECT{
- T centerx;
- T centery;
- T width;
- T height;
- double angle;
- };
- //定位点识别结果
- struct LOCATE_POINT_RESULT :OBJ_RESULT, OBJ_RECT<float>{
- };
- //二维码识别结果
- struct CODE_RESULT :OBJ_RESULT, OBJ_RECT<float>{
- std::string qr_str;
- bool is_stu_id;
- };
- struct CLIP_RESULT{
- //在原试卷的位置
- //图像数据地址
- unsigned char * img_data;
- //图像数据大小
- unsigned long img_data_size;
- //编号
- int index;
- //区域名称
- string area_name;
- };
- struct KGUANTI_OPTION_RESULT :OBJ_RECT<float>{
- float features[9];
- };
- //题目识别结果
- struct QUESTION_RESULT :OBJ_RESULT{
- string question_code;
- identify::OMR_QUESTION_TYPE omr_question_type;
- bool identifyed;
- int total; // 选做题总数
- int required; // 选做题需要选择几个
- int xuanze; // 当前题目是选择的第几个
- string question_code_all;// 选做题所有题号
- string question_code_temp;// 判断题组概念(question_code_all与question_code_temp不同时,是题组)
- double maxscore; //0没有小问
- QUESTION_RESULT(){
- total = 0; required = 0; xuanze = -1;
- }
- };
- //客观题识别结果
- struct KEGUANTI_RESULT :QUESTION_RESULT{
- OMR_QUESTION_STATE question_state;
- string answer;
- vector<KGUANTI_OPTION_RESULT> option;
- };
- //切割区域识别结果
- struct CUT_AREA_RESULT :OBJ_RESULT, OBJ_RECT<float>{
- std::string area_name;
- std::vector<unsigned char> img_data;
- int area_index;
- int area_sub_index;
- int is_cut; //0:原来false,1原来true,2特殊处理,不带f图片
- std::string area_name_by_questionNo;
- };
- //填空题识别结果
- struct TIANKONGTI_RESULT :QUESTION_RESULT, OBJ_RECT<float>{
- float question_score;
- bool isright;
- };
- //主观题识别结果
- struct ZHUGUANTI_RESULT :QUESTION_RESULT{
- float question_score;
- OMR_QUESTION_STATE question_state;
- vector<OBJ_RECT<float>> option;
- };
- class OMR_RESULT{
- public:
- //是否已经正确识别
- bool identified;
- //识别信息
- string identify_msg;
- //逻辑页号
- long logic_page_number;
- //物理页号
- long phy_card_number;
- //图像文件路径
- string img_path;
- //图像文件路径
- string img_oldpath;
- bool is_same_exam_id;
- bool is_front_page;
- bool is_use_qr_code;
- bool examid_by_qr_code; // 是否识别二维码
- //该页索引
- int card_index;
- //识别二维码情况(1识别成功,0:未进入,-1识别失败)
- int card_qrFlag;
- //页名称
- string card_name;
- //试卷ID 重新识别时使用
- int paper_id;
- std::string online_card_paperid;
- std::string strMagicClassId;
- std::string strMagicStudentId;
- int schoolCardStatus; // 使用学号状态
- // 缺考标记
- bool quekaoFlag;
- //处理时间,毫秒
- int time;
- /************************************************************************/
- /* 二维码结果 */
- /************************************************************************/
- vector<CODE_RESULT> qr_result;
- //定位点读取结果
- vector<LOCATE_POINT_RESULT> locatepoint_result;
- /************************************************************************/
- /*客观题结果 */
- /************************************************************************/
- vector<KEGUANTI_RESULT> group_result;
- /************************************************************************/
- /* 图像切割结果 */
- /************************************************************************/
- vector<CUT_AREA_RESULT> cut_area_result;
- //填空题读取结果
- vector<TIANKONGTI_RESULT> tiankongti_result;
- //主观题读取结果
- vector<ZHUGUANTI_RESULT> zhutuanti_result;
- public:
- #ifdef _DEBUG
- OMR_RESULT(){
- }
- #endif
- void reset(){
- online_card_paperid = "";
- quekaoFlag = false;
- identified = false;
- identify_msg = "";
- logic_page_number = -1;
- phy_card_number=-1;
- img_path=-1;
- card_index=-1;
- card_name=-1;
- paper_id=-1;
- time=-1;
- qr_result.clear();
- locatepoint_result.clear();
- group_result.clear();
- cut_area_result.clear();
- tiankongti_result.clear();
- zhutuanti_result.clear();
- is_same_exam_id=true;
- is_front_page=false;
- is_use_qr_code=false;
- }
- };
- }
- }
|