123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452 |
- #include "StdAfx.h"
- #include "SchemaLoader.h"
- #include "..\EvaluationUtil\HttpClient.h"
- #include "..\ZLibWrapMemLib\UnZipFile.h"
- #include "..\Schema\schema_struct.h"
- #include "..\Identifier\schema_struct.h"
- #include <opencv2\opencv.hpp>
- #include <opencv2\xfeatures2d.hpp>
- #include "..\Schema\schema.h"
- #include "common.h"
- using namespace cv;
- using namespace schema;
- using namespace cv::xfeatures2d;
- CSchemaLoader::CSchemaLoader(void)
- {
- }
- CSchemaLoader::~CSchemaLoader(void)
- {
- }
- /*
- 初始化模板
- */
- void CSchemaLoader::SetPageDefault(identify::schema::ISCH_SCHEMA_PAGE& page)
- {
- //page.group_spacer =';';
- page.hei_du_ling_min_du =4;
- page.height =0;
- page.index =0;
- page.option_spacer =',';
- //page.unselect_char='*';
- page.width=0;
- }
- bool sort_string(ISCH_SCHEMA_CLIP x1, ISCH_SCHEMA_CLIP x2){
- if (atoi(x1.area_name_by_questionNo.c_str()) != atoi(x2.area_name_by_questionNo.c_str()))
- return atoi(x1.area_name_by_questionNo.c_str()) < atoi(x2.area_name_by_questionNo.c_str());
- else
- return x1.markUnitPart < x2.markUnitPart;
- }
- // 加载模板信息
- int CSchemaLoader::Load(std::string fileName, std::string muban_img_dir, schema::SCHEMA& schema_schema, boost::shared_ptr<const ISCH_Schema> & schema_identify, boost::shared_ptr<const HANDLE_INFO>& handleInfos)
- {
- boost::shared_ptr<HANDLE_INFO> handleInfos_0(new HANDLE_INFO);
- HANDLE_INFO & handleInfos_ = *handleInfos_0;
- CUnZipFile uzip(CString(fileName.c_str()));
- std::map<CString,std::vector<unsigned char>> map;
- while(uzip.HasMoreEntry()){
- CString fileNam;
- uzip.GetNextEntry(fileNam);
- char buffer[1024*8];
- int len;
- std::vector<unsigned char>& data =map[fileNam];
- data.reserve(1024*128);
- while((len = uzip.Read(buffer,1024*8))>0){
- if(data.capacity()<data.size()+len){
- int c=data.capacity()+1024*128;
- data.reserve(c);
- }
- int oldSize =data.size();
- data.resize(oldSize+len);
- char * dst =(char *)data.data()+oldSize;
- memcpy(dst,buffer,len);
- }
- }
- uzip.Close();
- std::map<CString,std::vector<unsigned char>>::iterator schemabytes= map.find(_T("schema.bytes"));
- if(schemabytes == map.end()){
- return SCH_LOAD_ERR_MISSINGFORMAT;
- }
- SCHEMA_VERSION version;
- std::vector<unsigned char>& data =schemabytes->second;
- serializor::SchemJsonSerializor::deserialize(std::string((char *)data.data(),data.size()),schema_schema,version);
- if(version!=CURRENT_SCHEMA_VERSTION)return SCH_LOAD_ERR_VERSIONCHANGE;
- if(schema_schema.state == 0) return SCH_LOAD_ERR_ZHUANGTAIBUZHENGQUE;
- boost::shared_ptr<ISCH_Schema> schema_identify_t(new ISCH_Schema);
- std::vector<identify::schema::ISCH_SCHEMA_PAGE>& schema_identify_ = *schema_identify_t;
- std::vector<schema::SCHEMA_QUESTION> &questions =schema_schema.questions;
- handleInfos_.resize(schema_schema.pages.size());
- schema_identify_.resize(schema_schema.pages.size());
- int j = 0;
- for (int idx_p=0;idx_p<schema_schema.pages.size();idx_p++)
- {
- PAGE_RESULT_HANDLE_INFO& handleInfo =handleInfos_[idx_p];
- schema::SCHEMA_PAGE& schema_page=schema_schema.pages[idx_p];
- /************************************************************************/
- /* 整理模板到结果中 */
- /************************************************************************/
- identify::schema::ISCH_SCHEMA_PAGE* page = &schema_identify_[idx_p];
- SetPageDefault(*page);
- page->index = idx_p;
- page->width =schema_page.width;
- page->height =schema_page.height;
- page->locatePoints.resize(schema_page.locatePoints.size());
- for (int idx_i = 0; idx_i < schema_page.locatePoints.size();idx_i++)
- {
- identify::schema::ISCH_SCHEMA_LOCATE_POINT& dst = page->locatePoints[idx_i];
- schema::SCHEMA_LOCATE_POINT& src = schema_page.locatePoints[idx_i];
- dst.centerx = src.centerx;
- dst.centery = src.centery;
- dst.width = src.width;
- dst.height = src.height;
- dst.nID = src.nID;
- }
- page->locateCrosses.resize(schema_page.locateCrosses.size());
- for (int idx_i = 0; idx_i < schema_page.locateCrosses.size(); idx_i++)
- {
- identify::schema::ISCH_SCHEMA_LOACTE_CROSS& dst = page->locateCrosses[idx_i];
- schema::SCHEMA_LOACTE_CROSS& src = schema_page.locateCrosses[idx_i];
- dst.centerx = src.centerx;
- dst.centery = src.centery;
- dst.width = src.width;
- dst.height = src.height;
- dst.nID = src.nID;
- dst.angle = src.angle;
- dst.sign = src.sign;
- }
- std::vector<identify::schema::ISCH_IDENTIFY_GROUP> groupsv;
- vector<identify::schema::ISCH_SCHEMA_ITEM> itemv;
- int nextItemId=1;
- handleInfo.page_index = schema_page.index;
- nextItemId = caulateGroupAndItem(schema_page.quekaobiaoji, nextItemId, itemv, groupsv, handleInfo.quekaoHandleInfo, GROUP_TYPE::QUEKAO);
- nextItemId = caulateGroupAndItem(schema_page.abjuanbjiaoji, nextItemId, itemv, groupsv, handleInfo.abjuanHandleInfo, GROUP_TYPE::NONE);
- nextItemId = caulateGroupAndItem(schema_page.tiantukaohao, nextItemId, itemv, groupsv, handleInfo.tiantukaohaoHandleInfo, GROUP_TYPE::TIANTUKAOHAO);
- nextItemId = caulateGroupAndItem2(schema_page.xuanzuoti, nextItemId, itemv, groupsv, handleInfo.xuanzuotiHandleInfo, GROUP_TYPE::XUANZUOTI);
- nextItemId = caulateGroupAndItem(schema_page.keguantiMatrix, nextItemId, itemv, groupsv, handleInfo.keguantiHandleInfo, GROUP_TYPE::KEGUANTI);
- std::map<int,schema::SCHEMA_QUESTION*> index_id_question;
- std::map<std::string, schema::SCHEMA_QUESTION*> index_questionCode_question;
- for (int idx_i=0;idx_i<questions.size();idx_i++)
- {
- index_id_question[questions[idx_i].nID]=&questions[idx_i];
- index_questionCode_question[questions[idx_i].question_code_new]=&questions[idx_i];
- }
- for (int idx_i = 0; idx_i<schema_page.keguantiMatrix.size(); idx_i++)
- {
- schema::SCHEMA_MATRIX_KEGUANTI& ke = schema_page.keguantiMatrix[idx_i];
- KEGUANTI_RESULT_HANDLE_INFO & khi = handleInfo.keguantiHandleInfo[idx_i];
- khi.group_question_count.resize(ke.group_count);
- khi.group_index.resize(ke.group_count);
- khi.question_code.resize(ke.question_count);
- for (int idx_g=0,idx_q=0;idx_g<ke.group_count;idx_g++)
- {
- khi.group_question_count[idx_g]=ke.group_size[idx_g];
- for (int idx_g_i=0;idx_g_i<ke.group_size[idx_g]&&idx_q<ke.question_count;idx_g_i++,idx_q++)
- {
- for (int k=0;k<questions.size();k++)
- {
- if(questions[k].nID == ke.question_ids[idx_q]){
- int group_index = khi.group_index[idx_g];
- khi.question_code[idx_q] = questions[k].question_code_new;
- switch (questions[k].questionType&schema::QTF_QUESTION_TYPE_MASK){
- //单选
- case schema::QuestionType::DANXUANTI:groupsv[group_index].omr_out_type = identify::schema::OMR_OUT_TYPE_SINGLE_STRICT; break;
- case schema::QuestionType::PANDUANTI:groupsv[group_index].omr_out_type = identify::schema::OMR_OUT_TYPE_SINGLE_STRICT; break;
- //多选
- case schema::QuestionType::DUOXUANTI:groupsv[group_index].omr_out_type = identify::schema::OMR_OUT_TYPE_MUTIL_STRICT; break;
- //主观题
- case schema::ZHUGUANTI:groupsv[group_index].omr_out_type = identify::schema::OMR_OUT_TYPE_SINGLE_STRICT; break;
- case schema::TIANKONGTI:groupsv[group_index].omr_out_type = identify::schema::OMR_OUT_TYPE_SINGLE_STRICT; break;
- }
- break;
- }
- }
- }
- }
- }
- for (int idx_i=0;idx_i<schema_page.xuanzuoti.size();idx_i++)
- {
- schema::SCHEMA_MATRIX_XUANZUOTI& ke = schema_page.xuanzuoti[idx_i];
- XUANZUOTI_RESULT_HANDLE_INFO & khi=handleInfo.xuanzuotiHandleInfo[idx_i];
- khi.mark_unit.resize(khi.group_index.size());
- khi.mark_unit_question_code.resize(khi.group_index.size());
- khi.option_question_code.resize(khi.group_index.size());
- khi.xuantishu.resize(khi.group_index.size());
- for (int idx=0;idx<khi.group_index.size();idx++)
- {
- if(ke.xuantishu==1){
- groupsv[khi.group_index[idx]].omr_out_type = identify::schema::OMR_OUT_TYPE_SINGLE_NONSTRICT;
- }else{
- groupsv[khi.group_index[idx]].omr_out_type = identify::schema::OMR_OUT_TYPE_MUTIL_STRICT;
- }
- }
- vector<string> questions1;
- split(ke.outputcharsnew, (string)";", &questions1);
- for (int index_group=0;index_group<khi.group_index.size();index_group++)
- {
- khi.option_question_code[index_group].resize(questions1.size());
- khi.xuantishu[index_group]=ke.xuantishu;
- for (int index1=0;index1<questions1.size();index1++)
- {
- vector<string> questions2;
- split(questions1[index1],(string)",",&questions2);
- khi.option_question_code[index_group][index1]=questions2;
- for (int index2=0;index2<questions2.size();index2++)
- {
- if(index_questionCode_question.find(questions2[index2])!=index_questionCode_question.end()){
- std::vector<std::string>& markunit=khi.mark_unit[index_group];
- schema::SCHEMA_QUESTION * question = index_questionCode_question[questions2[index2]];
- int markunit_index =-1;
- char szmarkunit[32];
- sprintf_s(szmarkunit,"%d",question->nMarkUnit);
- for (int index_markunit=0;index_markunit<markunit.size();index_markunit++)
- {
- if(markunit[index_markunit] ==szmarkunit){
- markunit_index=index_markunit;
- break;
- }
- }
- if(markunit_index<0){
- markunit.push_back(szmarkunit);
- khi.mark_unit_question_code[index_group].push_back(question->question_code_new);
- }else{
- khi.mark_unit_question_code[index_group][markunit_index].append(",");
- khi.mark_unit_question_code[index_group][markunit_index].append(question->question_code_new);
- }
- }
- }
- }
- }
- }
- page->codes.resize(schema_page.codes.size());
- for (int idx_i = 0; idx_i < schema_page.codes.size(); idx_i++)
- {
- identify::schema::ISCH_SCHEMA_CODE& dst = page->codes[idx_i];
- schema::SCHEMA_CODE& src = schema_page.codes[idx_i];
- dst.centerx = src.centerx;
- dst.centery = src.centery;
- dst.width = src.width;
- dst.height = src.height;
- dst.nID = src.nID;
- dst.bDirection = (identify::schema::ISCH_DIRECTION)(int)src.bDirection;
- }
- page->groups=groupsv;
- page->items=itemv;
- page->cutAreas.resize(schema_page.clips.size() + schema_page.clips2.size());
- int nClips2 = 0;
- for (int idx_i = 0; idx_i < schema_page.clips2.size(); idx_i++)
- {
- identify::schema::ISCH_SCHEMA_CLIP& dst = page->cutAreas[idx_i];
- schema::SCHEMA_CLIP& src = schema_page.clips2[idx_i];
- dst.centerx = src.centerx;
- dst.centery = src.centery;
- dst.width = src.width;
- dst.height = src.height;
- dst.nID = src.nID;
- dst.area_name = src.area_name;
- dst.area_name_by_questionNo = src.area_name_by_questionNoNew;
- dst.markUnit = src.markUnit;
- dst.markUnitPart = src.markUnitPart;
- nClips2++;
- }
- for (int idx_i = 0; idx_i < schema_page.clips.size(); idx_i++)
- {
- identify::schema::ISCH_SCHEMA_CLIP& dst = page->cutAreas[idx_i + nClips2];
- schema::SCHEMA_CLIP& src = schema_page.clips[idx_i];
- dst.centerx = src.centerx;
- dst.centery = src.centery;
- dst.width = src.width;
- dst.height = src.height;
- dst.nID = src.nID;
- dst.area_name = src.area_name;
- dst.area_name_by_questionNo = src.area_name_by_questionNoNew;
- dst.markUnit = src.markUnit;
- dst.markUnitPart = src.markUnitPart;
- }
- std::sort(page->cutAreas.begin(), page->cutAreas.end(), sort_string);
- CString imgName ;
- imgName.Format(_T("%05d.jpg"),schema_page.nID);
- vector<uchar> & fff =map[imgName];
- Mat img = imdecode(fff,CV_LOAD_IMAGE_GRAYSCALE);
- double angle =schema_page.angle;
- double a = fmod(fmod(angle,360)+360,360);
- int nWidth,nHeight;
- if((a>45&&a<=135)||(a>45+180&&a<=135+180)){
- nHeight = img.cols;
- nWidth = img.rows;
- }else{
- nWidth = img.cols;
- nHeight = img.rows;
- }
- page->width = nWidth;
- page->height = nHeight;
- double sina = sin(CV_PI*angle/180);
- double cosa = cos(CV_PI*angle/180);
- CvPoint2D32f center0 = cvPoint2D32f(img.cols/2.0,img.rows/2.0);
- CvPoint2D32f center1 = cvPoint2D32f(nWidth/2.0,nHeight/2.0);
- float offsetx = center1.x - (cosa*center0.x+sina*center0.y);
- float offsety = center1.y - (-sina*center0.x+cosa*center0.y);
- float data[6]={cosa,sina,offsetx,-sina,cosa,offsety};
- Mat m(2,3,CV_32F,data);
- Mat img_rotated;
- warpAffine(img,img_rotated,m,cvSize(nWidth,nHeight));
- CString imgFileName;
- char imgfilename_a [1024];
- imgFileName.Format(_T("%s\\%05d_original.jpg"),CString(muban_img_dir.c_str()),idx_p);
- WideCharToMultiByte(CP_ACP,0,imgFileName,-1,imgfilename_a,1024,NULL,NULL);
- imwrite(imgfilename_a,img);
- imgFileName.Format(_T("%s\\%05d.jpg"), CString(muban_img_dir.c_str()), idx_p);
- WideCharToMultiByte(CP_ACP,0,imgFileName,-1,imgfilename_a,1024,NULL,NULL);
- imwrite(imgfilename_a,img_rotated);
- img.release();
- IplImage * img_smoothd = &IplImage(img_rotated);
- cvSmooth(img_smoothd, img_smoothd, CV_GAUSSIAN, 5);
-
- caculateLocateArea(img_rotated,schema_page.locateAreas,page->locateAreas);
- std::vector<identify::schema::ISCH_IDENTIFY_AREA>& assistLocateArea = page->assistLocateArea;
- caculateLocateArea(img_rotated,schema_page.quekaobiaoji,assistLocateArea);
- caculateLocateArea(img_rotated,schema_page.abjuanbjiaoji,assistLocateArea);
- caculateLocateArea(img_rotated,schema_page.tiantukaohao,assistLocateArea);
- caculateLocateArea(img_rotated,schema_page.keguantiMatrix,assistLocateArea);
- caculateLocateArea(img_rotated,schema_page.xuanzuoti,assistLocateArea);
- }
- schema_identify = schema_identify_t;
- handleInfos = handleInfos_0;
- return SCH_LOAD_SUCCESS;
- }
- //选做题
- template<class T, class T2> int CSchemaLoader::caulateGroupAndItem2(std::vector<T> &matrix, int nextItemId, vector<identify::schema::ISCH_SCHEMA_ITEM> &itemv, std::vector<identify::schema::ISCH_IDENTIFY_GROUP> &groupsv, std::vector<T2>& handleInfos, GROUP_TYPE _type)
- {
- for (int i=0;i<matrix.size();i++)
- {
- T2 hi;
- T& k = matrix[i];
- std::vector<std::string> answers;
- split((std::string)k.outputcharsnew,(std::string)";",&answers);
- if (k.direction == schema::Horizontal){
- for (int m=0;m<k.nRows;m++)
- {
- hi.group_index.push_back(groupsv.size());
- identify::schema::ISCH_IDENTIFY_GROUP group;
- group.itemCount = k.nCols;
- group.omr_out_type = identify::schema::OMR_OUT_TYPE_SINGLE_STRICT;
- group.group_type = _type;
- for (int n=0;n<k.nCols;n++)
- {
- identify::schema::ISCH_SCHEMA_ITEM item;
- double hGap = k.nCols>1?(k.width-(k.optionWidth*k.nCols))/(k.nCols-1):0;
- double vGap = k.nRows>1?(k.height-(k.optionHeight*k.nRows))/(k.nRows-1):0;
- item.centerx = (k.centerx-k.width/2)+n*(k.width+hGap)/k.nCols+k.optionWidth/2.0;
- item.centery = (k.centery-k.height/2)+m*(k.height+vGap)/k.nRows+k.optionHeight/2.0;
- item.width = k.optionWidth;
- item.height = k.optionHeight;
- item.nID = nextItemId++;
- strcpy_s(item.OutChar,answers[n].c_str());
- group.itemIndex.push_back(itemv.size());
- itemv.push_back(item);
- }
- groupsv.push_back(group);
- }
- }else{
- for (int n=0;n<k.nCols;n++)
- {
- hi.group_index.push_back(groupsv.size());
- identify::schema::ISCH_IDENTIFY_GROUP group;
- group.itemCount = k.nRows;
- group.omr_out_type = identify::schema::OMR_OUT_TYPE_SINGLE_STRICT;
- for (int m=0;m<k.nRows;m++)
- {
- identify::schema::ISCH_SCHEMA_ITEM item;
- double hGap = k.nCols>1?(k.width-(k.optionWidth*k.nCols))/(k.nCols-1):0;
- double vGap = k.nRows>1?(k.height-(k.optionHeight*k.nRows))/(k.nRows-1):0;
- item.centerx = (k.centerx-k.width/2)+n*(k.width+hGap)/k.nCols+k.optionWidth/2.0;
- item.centery = (k.centery-k.height/2)+m*(k.height+vGap)/k.nRows+k.optionHeight/2.0;
- item.width = k.optionWidth;
- item.height = k.optionHeight;
- item.nID = nextItemId++;
- strcpy_s(item.OutChar,answers[m].c_str());
- group.itemIndex.push_back(itemv.size());
- itemv.push_back(item);
- }
- groupsv.push_back(group);
- }
- }
- handleInfos.push_back(hi);
- }
- return nextItemId;
- }
- template<class T, class T2> int CSchemaLoader::caulateGroupAndItem(std::vector<T> &matrix, int nextItemId, vector<identify::schema::ISCH_SCHEMA_ITEM> &itemv, std::vector<identify::schema::ISCH_IDENTIFY_GROUP> &groupsv,
- std::vector<T2>& handleInfos, GROUP_TYPE _type)
- {
- for (int i=0;i<matrix.size();i++)
- {
- T2 hi;
- T& k = matrix[i];
- std::vector<std::string> answers;
- split((std::string)k.outputchars,(std::string)",",&answers);
- if(k.direction == schema::Horizontal){
- for (int m=0;m<k.nRows;m++)
- {
- hi.group_index.push_back(groupsv.size());
- identify::schema::ISCH_IDENTIFY_GROUP group;
- group.group_type = _type;
- group.itemCount = k.nCols;
- group.omr_out_type = identify::schema::OMR_OUT_TYPE_SINGLE_STRICT;
- for (int n=0;n<k.nCols;n++)
- {
- identify::schema::ISCH_SCHEMA_ITEM item;
- double hGap = k.nCols>1?(k.width-(k.optionWidth*k.nCols))/(k.nCols-1):0;
- double vGap = k.nRows>1?(k.height-(k.optionHeight*k.nRows))/(k.nRows-1):0;
- item.centerx = (k.centerx-k.width/2)+n*(k.width+hGap)/k.nCols+k.optionWidth/2.0;
- item.centery = (k.centery-k.height/2)+m*(k.height+vGap)/k.nRows+k.optionHeight/2.0;
- item.width = k.optionWidth;
- item.height = k.optionHeight;
- item.nID = nextItemId++;
- strcpy_s(item.OutChar,answers[n].c_str());
- group.itemIndex.push_back(itemv.size());
- itemv.push_back(item);
- }
- groupsv.push_back(group);
- }
- }else{
- for (int n=0;n<k.nCols;n++)
- {
- hi.group_index.push_back(groupsv.size());
- identify::schema::ISCH_IDENTIFY_GROUP group;
- group.group_type = _type;
- group.itemCount = k.nRows;
- group.omr_out_type = identify::schema::OMR_OUT_TYPE_SINGLE_STRICT;
- for (int m=0;m<k.nRows;m++)
- {
- identify::schema::ISCH_SCHEMA_ITEM item;
- double hGap = k.nCols>1?(k.width-(k.optionWidth*k.nCols))/(k.nCols-1):0;
- double vGap = k.nRows>1?(k.height-(k.optionHeight*k.nRows))/(k.nRows-1):0;
- item.centerx = (k.centerx-k.width/2)+n*(k.width+hGap)/k.nCols+k.optionWidth/2.0;
- item.centery = (k.centery-k.height/2)+m*(k.height+vGap)/k.nRows+k.optionHeight/2.0;
- item.width = k.optionWidth;
- item.height = k.optionHeight;
- item.nID = nextItemId++;
- strcpy_s(item.OutChar,answers[m].c_str());
- group.itemIndex.push_back(itemv.size());
- itemv.push_back(item);
- }
- groupsv.push_back(group);
- }
- }
- handleInfos.push_back(hi);
- }
- return nextItemId;
- }
|