123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443 |
- #pragma once
- #include "OnLineCardSchemaStruct.h"
- #include "schema_struct.h"
- #include "identify_struct.h"
- #ifdef IDENTIFIER_EXPORTS
- #define IDENTIFIER_API __declspec(dllexport)
- #else
- #define IDENTIFIER_API __declspec(dllimport)
- #endif
- namespace OnLineCard{
- struct schema_const_param{
- //试卷宽度(扫描后图片的大小(可以使用像素),越大越准确)
- int shijuanwidth;
- //试卷高度
- int shijuanheight;
- //内容高度(考试文本最顶部内容到页码底部间距离)
- int contenth;
- //内容顶部缩进(第一个定位点上边框到考试文本内容最上边内容距离)
- int content_margin_top;
- //第一块最小高度(试卷最左上角的矩形框要求的最小高度)
- int first_content_min_height;
- //内容(左侧)检测x偏移量
- int content_detect_left_offsetx;
- //内容(右侧)检测x偏移量
- int content_detect_right_offsetx;
- //内容检测宽度
- int content_detect_w;
- /************************************************************************/
- /* 定位点相关常亮 */
- /************************************************************************/
- //上下左右4边定位点的最大最小宽高
- double main_locate_point;
- //主定位点在4个不同方向的最小宽度
- int minw[4];
- //主定位点在4个不同方向的最大宽度
- int maxw[4];
- //主定位点在4个不同方向的最小高度
- int minh[4];
- //主定位点在4个不同方向的最大高度
- int maxh[4];
- //版本定位点检测区域相对第一个定位点的位置 的x坐标
- int version_detect_offsetx;
- //版本定位点检测区域相对第一个定位点的位置 的y坐标
- int version_detect_offsety;
- //版本定位点检测区域宽度
- int version_detect_width;
- //版本定位点检测区域高度
- int version_detect_height;
- //版本定位点在4个不同方向的最小宽度
- int version_minw[4];
- //版本定位点在4个不同方向的最大宽度
- int version_maxw[4];
- //版本定位点在4个不同方向的最小高度
- int version_minh[4];
- //版本定位点在4个不同方向的最大高度
- int version_maxh[4];
- //题目定位点的最大宽高
- int left_offsetx;
- int right_offsetx;
- int qd_detect_w;
- int maxw2;
- int minw2;
- int maxh2;
- int minh2;
- /************************************************************************/
- /* 试卷条码位置相关常量 */
- /************************************************************************/
- //试卷条码位置(相对第一个定位点位置,大概位置不到真正的二维码区域,可以理解是放大扫描空间的图片区域)
- int paper_bar_offsetx;
- int paper_bar_offsety;
- int paper_bar_width;
- int paper_bar_height;
- /************************************************************************/
- /* 学生条码位置相关常量 */
- /************************************************************************/
- //试卷条码位置(相对第一个定位点位置,大概位置不到真正的二维码区域,可以理解是放大扫描空间的图片区域)
- int paper_bar_offsetx1;
- int paper_bar_offsety1;
- int paper_bar_width1;
- int paper_bar_height1;
- //缺考标记相关参数
- int quekao_item_offset_x;
- int quekao_item_offset_y;
- int quekao_item_width;
- int quekao_item_height;
- //学号
- #define stuid_max_question_count 14
- int stuid_max_question_count2;
- int stuid_question_offset[stuid_max_question_count];//每题x轴偏移量
- int stuid_tudian_w; //涂点宽度
- int stuid_tudian_h; //涂点高度
- int stuid_item_offset_y; //第一排涂点y轴偏移量
- int stuid_item_offset_len; //每排Y轴偏移量,因为是表格,所以间隔固定
- /************************************************************************/
- /* 客观题相关常量 */
- /************************************************************************/
- //每一横排最大选择题数量(存储空间)
- #define xuanze_max_question_count 24
- #define xuanze_max_item_count 4
- //每一横排最大选择题数量
- int xuanze_max_question_count2;
- int xuanze_question_offset[xuanze_max_question_count];//每题x轴偏移量
- int xuanze_item_offset[xuanze_max_item_count];//每题涂点y轴偏移量
- int xuanze_question_header_offsety;//题号的y坐标偏移
- int tudian_w;//涂点宽度
- int tudian_h;//涂点高度
- int xuanze_item_offset_y; //第一排涂点y轴偏移量
- int xuanze_item_offset_len; //每排Y轴偏移量,因为是表格,所以间隔固定
- /************************************************************************/
- /* 不定项选择相关常量(多选题) */
- /************************************************************************/
- //每一横排最大选择题数量(存储空间)
- #define xuanze_max_question_count3 24
- #define xuanze_max_item_count3 10
- //每一横排最大选择题数量
- int xuanze_max_question_count4;
- int xuanze_question_offset3[xuanze_max_question_count3];//每题x轴偏移量
- int xuanze_item_offset3[xuanze_max_item_count3];//每题涂点y轴偏移量
- int xuanze_question_header_offsety3;//题号的y坐标偏移
- int tudian_w3;//涂点宽度
- int tudian_h3;//涂点高度
- int xuanze_item_offset_y3; //第一排涂点y轴偏移量
- int xuanze_item_offset_len3; //每排Y轴偏移量,因为是表格,所以间隔固定
- /************************************************************************/
- /* 填空题相关常量 (江苏卷) */
- /************************************************************************/
- //评分框宽度
- int tikong_w;
- //评分框高度
- int tikong_h;
- //每一横排最大填空题数量
- #define tiangkong_max_question_count 2
- //每题x轴偏移量(相对题目定位点的偏移)
- int tiangkong_question_offset[tiangkong_max_question_count];
- //每题结束位置x轴偏移量
- int tiangkong_end_offset[tiangkong_max_question_count];
- //每题开始位置x轴偏移量
- int tiangkong_start_offset[tiangkong_max_question_count];
- //填空题评分框y偏移量
- int tiankong_offsety;
- //填空题切割区域y偏移量(相对题目定位点的偏移)
- int tiankong_area_offsety;
- //填空题切割区域高度
- int tiankong_area_height;
- //评分框宽度阀值(动态检查时用到)
- int tiankong_w2;
- //评分框宽度阀值误差范围
- int tiankong_w3;
- //评分框高度阀值
- int tiankong_h2;
- //评分框高度阀值误差范围
- int tiankong_h3;
- #define tiankong_per_mode_type 5
- //数组0:全国 1:江苏 2:浙江 3:大分数
- //评分框宽度
- int tikong_w_arr[tiankong_per_mode_type];
- //评分框高度
- int tikong_h_arr[tiankong_per_mode_type];
- //每题x轴偏移量(相对题目定位点的偏移),自定义一行一个填空题
- int tiangkong_question_offset_arr[tiankong_per_mode_type];
- //每题结束位置x轴偏移量
- int tiangkong_end_offset_arr[tiankong_per_mode_type];
- //每题开始位置x轴偏移量
- int tiangkong_start_offset_arr[tiankong_per_mode_type];
- //填空题评分框y偏移量
- int tiankong_offsety_arr[tiankong_per_mode_type];
- //填空题切割区域y偏移量(相对题目定位点的偏移)
- int tiankong_area_offsety_arr[tiankong_per_mode_type];
- //填空题切割区域高度
- int tiankong_area_height_arr[tiankong_per_mode_type];
- /************************************************************************/
- /* 填空题相关常量 (全国卷) 选择题和填空题共用一个题目定位点 */
- /************************************************************************/
- int qtikong_w;//评分框宽度
- int qtikong_h;//评分框高度
- //每一横排最大填空题数量
- #define qtiangkong_max_question_count 1
- #define qtiangkong_max_pai_count 4
- //每题x轴偏移量
- int qtiangkong_question_offset[tiangkong_max_question_count];
- //每题结束位置x轴偏移量
- int qtiangkong_end_offset[tiangkong_max_question_count];
- //每题开始位置x轴偏移量
- int qtiangkong_start_offset[tiangkong_max_question_count];
- //每题排y轴偏移量
- int qtiangkong_pai_offset[qtiangkong_max_pai_count];
- //填空题评分框y偏移量
- int qtiankong_offsety;
- //填空题切割区域y偏移量
- int qtiankong_area_offsety;
- //填空题切割区域高度
- int qtiankong_area_height;
- //评分框宽度阀值
- int qtiankong_w2;
- //评分框宽度阀值误差范围
- int qtiankong_w3;
- //评分框高度阀值
- int qtiankong_h2;
- //评分框高度阀值误差范围
- int qtiankong_h3;
- /************************************************************************/
- /* 主观题相关常量 */
- /************************************************************************/
- //每一横排评分框数量
- #define zhuguanti_max_question_count 23
- int zhuguanti_question_offset[zhuguanti_max_question_count];//每评分框x轴偏移量
- int zhuguanti_w;//评分框宽度
- int zhuguanti_h;//评分框高度
- int zhuguanti_h2;//评分框高度阀值(评分数据框上下两边距离)
- int zhuguanti_h3;//评分框高度阀值误差范围(允许的上下两边实际误差范围)
- //主观题偏移位置
- int zhuguanti_offsetx;
- int zhuguanti_offsety;
- int zhuguanti_item_count;//主观题总共格子数(目前23个)
- //主观题最后一个格子相对右边地位点的偏移量(右边第一个分数框到右边题目定位点距离)
- int zhuguanti_r_offsetx;
- int zhuguanti_r_offsety;
- //主管题格子的宽高
- int zhuguanti_item_w;
- int zhuguanti_item_h;
- double main_locate_point_distance;
- //题目定位点距离
- double question_locate_point_distance;
- int group_count;
- int group_question_count;
- /************************************************************************/
- /* 附加题相关常量 */
- /************************************************************************/
- #define qxuanzuoti_max_count 4
- int qxuanzuoti_question_offsetx[qxuanzuoti_max_count];
- int qxuanzuoti_question_offsety[qxuanzuoti_max_count];
- int qxuanzuoti_item_w;
- int qxuanzuoti_item_h;
- };
- //分析结果
- struct OnlineAnalyseResult{
- //填涂项数量
- int cellNum;
- //填涂项灰度平均值
- int cellAvgGray;
- //全局背景灰度
- int backGroundGray;
- //填涂项结果
- struct itemResult{
- //黑度
- double heidu;
- //模糊度
- double mohudu;
- //相对面积(黑点面积与总面积之比)
- double xiangdui_mianji;
- //相对值(有灰度与面积计算的一个参考值)
- double xiangdui_value;
- //填涂区域的平均灰度
- int avg_gray;
- //相对背景被涂黑点数
- int gray_num;
- //涂点大小
- int cell_size;
- //字符区域大小
- int char_area_size;
- //字符区域黑色点数(统计选项的字符区域的灰度判定为黑色的点数,用于统计试卷该选项全局的平均字符黑点数)
- int char_area_black_count;
- //字符区域黑色点的平均灰度
- double char_area_avg_gray;
- }itemAnalyseResult[2048];
- //平均黑度
- double avg_heidu;
- //浮动黑度
- double float_heidu;
- //黑度基准
- double benchmarkBlk;
- //所有点最大黑度的平均值
- double avgMax_heidu;
- //面积基准
- double benchmarkAreaBlk;
- //黑度阀值
- int heidu_fazhi;
- //字符区域黑点数的平均值
- double char_area_black_avg[16];
- };
- class IDENTIFIER_API PageIdentify
- {
- public:
- PageIdentify();
- ~PageIdentify();
- //识别指定图像
- int Identify(const IplImage* img, void* out_result, int out_size);
- // 识别
- int Identify();
- //根据指定页面
- int Identify_impl();
- int BaseCheck();
- int ClipImg(SchemaPage& schemaPage, IplImage * dst);
- int ReadQuestionScore(SchemaPage &schemaPage, IplImage * dst, CvMemStorage* storage);
- int ReadKeGuanTi(SchemaPage &schemaPage, IplImage * dst);
- int ReadStudentID(SchemaPage &schemaPage, IplImage * dst);
- bool ReadQuekaoFlag(SchemaPage &schemaPage, IplImage * dst);
- void InitalizeTempVar();
- //计算涂点属性
- inline int caculate_cell_property(SchemaPage& schemaPage, SchemaItem &item, IplImage * dst, int &cellSize, double &refArea, double &avg_gray, int &grayNum, double &mo_hu_du, double &gao_heidu,/*字符区域大小*/int &char_area_size,/*字符区域黑色点数(统计选项的字符区域的灰度判定为黑色的点数,用于统计试卷该选项全局的平均字符黑点数)*/int& char_area_black_count,/*字符区域黑色点的平均灰度*/double& char_area_avg_gray, int flag = 0);
- //获取全局背景灰度,通过统计所有涂点周围像素(灰度不小于160)的灰度平均值获得
- int caculate_global_background(SchemaPage& schemaPage, IplImage * dst, bool flag = false);//flag 检查学号
- //分析全局属性
- int analyseOmrPanoramic(SchemaPage& schemaPage);
- //根据分析结果生成结果字符串
- int GenerateOmrStr(SchemaPage& schemaPage);
- int GetBlackArea(const IplImage * dst);
- int SaveLocateInfo(SchemaPage& schemaPage, std::vector<CvPoint2D32f> &relationKey, std::vector<CvPoint2D32f> &relationValue);
- inline int GetRect(const int centerx, const int centery, const int width, const int height, RESULT_RECT& result_rect);
- public:
- template<class T> void SaveRect(CvRect& rect, T& result);
- template<class T> inline CvRect GetCVRect(T& code)
- {
- CvRect result_rect;
- result_rect.x = code.centerx - code.width / 2;
- result_rect.y = code.centery - code.height / 2;
- result_rect.width = code.width;
- result_rect.height = code.height;
- return result_rect;
- }
- template<class T > inline void DrawObjRect(IplImage * dst, T& obj_result, CvScalar& scalar);
- inline int GetRect2(const int centerx, const int centery, const int width, const int height, RESULT_RECT& result_rect);
- BOOL FindQuestionLocatePoint(IplImage * dst, SchemaLocatePoint& lp1, CvPoint2D32f& point1);
- double GetDistance(CvPoint2D32f point1, CvPoint2D32f point2);
- int FindQuestionLocatePoints(SchemaPage& schemaPage, IplImage * dst);
- template<typename T>inline int GetTransformPoint(CvMat& mat, T& srcx, T& srcy, T& dstx, T& dsty){
- dstx = (T)(CV_MAT_ELEM(mat, float, 0, 0)*srcx + CV_MAT_ELEM(mat, float, 0, 1)*srcy + CV_MAT_ELEM(mat, float, 0, 2));
- dsty = (T)(CV_MAT_ELEM(mat, float, 1, 0)*srcx + CV_MAT_ELEM(mat, float, 1, 1)*srcy + CV_MAT_ELEM(mat, float, 1, 2));
- return identify::result::IDF_SUCCESS;
- }
- int GetTianKongTiRedCount(IplImage * dst, const CvRect& rect_normal, const CvRect& rect_detect, int count, int multi);
- int GetZhuGuanTiRedCount(IplImage * dst, const CvRect& rect, const CvRect& normal_rect, int * red_counts, int * red_in_counts, int count, int multi, bool bTianKongTi = false);
- BOOL GetRedBinary(IplImage * dst, const CvRect& rect_detect, IplImage ** red_binary);
- int mycaculate_global_background(SchemaItem items[], int itemCount, IplImage * dst);
- int myanalyseOmrPanoramic(OnlineAnalyseResult& anlyseResultTemp, int count);
- int myGenerateOmrStr(OnlineAnalyseResult& anlyseResultTemp, int count);
- int ReadXuanZuoTi(SchemaPage& schemaPage, SchemaQuestionScore& qs, IplImage * dst);
- int GenerateOmrStr(SchemaPage& schemaPage, std::string &ret);
- void SetUseQr(std::string strQr, bool bUse);
- void SetOnlineScanType(int nOnlineScanType);
- void SetPaperMode(int mode);
- void SetIdentiforMode(int subject, int mode);
- void SetScanMode(int type);
- schema_const_param m_default_schema_param;
- int JiaoZheng_20200418(IplImage * src0, IplImage * &dst_img, const std::vector<CvRect> & top_locate_point_list, const std::vector<CvRect> & bottom_locate_point_list,
- const std::vector<CvRect> & word_location_point_list, int dir,
- double, double, int word_w, int word_h);
- int JiaoZheng_20200418_first(IplImage * src0, IplImage * &dst_img,
- const std::vector<CvRect> & top_locate_point_list, const std::vector<CvRect> & bottom_locate_point_list, const std::vector<CvRect> & word_location_point_list,
- int dir);
- int JiaoZheng_20200418_second_four(IplImage * src0_, IplImage * &dst_img,
- const std::vector<CvRect> & top_locate_point_list, const std::vector<CvRect> & bottom_locate_point_list, const std::vector<CvRect> & word_location_point_list,
- int dir);
- int JiaoZheng_20200418_second_five(IplImage * src0_, IplImage * &dst_img,
- const std::vector<CvRect> & top_locate_point_list, const std::vector<CvRect> & bottom_locate_point_list, const std::vector<CvRect> & word_location_point_list,
- int dir);
- int xuanzhuan(IplImage * src0, IplImage * &dst_img, CvRect myRect);
- void myscale_shema_param0(const schema_const_param& default_schema_const_param, schema_const_param& schema_param, double scale);
- void CalcPos(const Pos&pos, const CvPoint& offset, double w_scale, double h_scale, int ¢er_x, int ¢er_y, int &w, int &h);
- void InitScoreArea(SchemaQuestionScore&sqs, const ScoreBox&box, CvPoint offset, double w_scale, double h_scale);
- int createSchema(const IplImage* src, IplImage* *dst, SchemaPage* *pageSchema, const char * result_path, std::string jiaozheng, bool bUseQr);
- string ReadQrCode(const IplImage* src);
- OnLineCard::PaperTemplate* m_pTemplate;
- void SetTemplate(OnLineCard::PaperTemplate*pT);
- void SetPageDefault(SchemaPage& page);
- int OnLineCardJZ(IplImage* src, IplImage* &dst_img, int nPageIndex, int dir, std::vector<CvRect>&main_locate_point, int &wordloctlt);
- int MyFindDingWeiDian(IplImage * src_gray_img, CvMemStorage* storage, schema_const_param &schema_param, std::vector<CvRect>& locate_point_list, int & _dir);
- int MyFindBottomDingWeiDian(IplImage * src_gray_img, CvMemStorage* storage, schema_const_param &schema_param, std::vector<CvRect>& locate_point_list, int & _dir);
- int GetQrCode(IplImage* dst_gray_img, schema_const_param &schema_param, std::vector<CvRect> &main_locate_point, std::vector<SchemaCode> &codev, std::string& paper_id, std::string& student_code, int code_type);
- void DrawSchema(IplImage * dst_img, SchemaPage* & pageSchema);
- double CalcRectArea(IplImage* src, const std::vector<CvRect> & top_locate_point_list, const std::vector<CvRect> & bottom_locate_point_list);
- std::vector<CvRect> m_vecBottom;
- int obj_index;
- OnlineAnalyseResult anlyseResult;
- //源图像
- IplImage *src;
- //纸张进入时的旋转角度
- FeedDirection feedDirection;
- //模板
- std::vector<SchemaPage*> *schemaPages;
- std::vector<CvPoint2D32f> m_relationKey;
- std::vector<CvPoint2D32f> m_relationValue;
- int dianshu_meihaomi;
- bool m_bUseQr;
- int m_nOnlineScanType;
- std::string m_strQrClass;
- int m_scantype;
- int m_paper_mode;
- void* out_result;
- identify::result::OMR_RESULT* omr_result;
- int m_subjectMode;
- int m_identiforMode;
- private:
- //识别范围结果保存
- std::vector<CvRect> item_result;
- float data[6];
- std::vector<CvPoint2D32f> m_question_locate_points;
- std::vector<BOOL> m_question_locate_point_found;
- std::vector<SchemaItem> m_items;
- public:
- RTL_CRITICAL_SECTION* m_althom_rcs;
- public:
- int m_nXianXiaDaFenType;
- bool m_nBxuanxiang;
- };
- }
|