#pragma once #include #include #include 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 }; templatestruct ISCH_SCHEMA_RECT_FIELD{ T centerx; T centery; T width; T height; }; struct ISCH_SCHEMA_ELEMENT_FIELD :ISCH_SCHEMA_RECT_FIELD{ 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 itemIndex; GROUP_TYPE group_type; }; struct ISCH_IDENTIFY_AREA{ ISCH_SCHEMA_LOCATE_AREA locate_area; std::vector locateAreasKeyPoints; cv::Mat locateAreasDescriptor; CvPoint locateAreasOffset; }; struct ISCH_SCHEMA_ZHUGUANTI :ISCH_SCHEMA_ELEMENT_FIELD, ISCH_QUESTION_BASIC{//题目分数 std::vector 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 locatePoints; std::vector locateCrosses; std::vector locateAreas; std::vector assistLocateArea; std::vector codes; std::vector groups; std::vector items; std::vector cutAreas; std::vector tiankongtis; std::vector zhuguantis; //多个选项之间的间隔字符 char option_spacer; //黑度灵敏度 int hei_du_ling_min_du; }; typedef std::vector 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 struct OBJ_RECT{ T centerx; T centery; T width; T height; double angle; }; //定位点识别结果 struct LOCATE_POINT_RESULT :OBJ_RESULT, OBJ_RECT{ }; //二维码识别结果 struct CODE_RESULT :OBJ_RESULT, OBJ_RECT{ 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 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 option; }; //切割区域识别结果 struct CUT_AREA_RESULT :OBJ_RESULT, OBJ_RECT{ std::string area_name; std::vector 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 question_score; bool isright; }; //主观题识别结果 struct ZHUGUANTI_RESULT :QUESTION_RESULT{ float question_score; OMR_QUESTION_STATE question_state; vector> 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 qr_result; //定位点读取结果 vector locatepoint_result; /************************************************************************/ /*客观题结果 */ /************************************************************************/ vector group_result; /************************************************************************/ /* 图像切割结果 */ /************************************************************************/ vector cut_area_result; //填空题读取结果 vector tiankongti_result; //主观题读取结果 vector 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; } }; } }