LocateTester.cpp 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331
  1. #include "StdAfx.h"
  2. #include "..\Schema\schema_struct.h"
  3. #include <opencv2\opencv.hpp>
  4. #include "LocateTester.h"
  5. #include "..\Identifier\schema_struct.h"
  6. #include "common.h"
  7. using namespace cv;
  8. using namespace schema;
  9. CLocateTester::CLocateTester(void) :m_isReady(true), m_isResultOk(false), _schema(new ISCH_Schema())
  10. {
  11. }
  12. CLocateTester::~CLocateTester(void)
  13. {
  14. }
  15. /*
  16. 初始化模板
  17. */
  18. void CLocateTester::SetPageDefault(ISCH_SCHEMA_PAGE& page)
  19. {
  20. //page.group_spacer =';';
  21. page.hei_du_ling_min_du =4;
  22. page.height =0;
  23. page.index =0;
  24. page.option_spacer =',';
  25. //page.unselect_char='*';
  26. page.width=0;
  27. }
  28. void CLocateTester::loadSchema(const schema::SCHEMA& schema, const std::vector<std::string>& img_paths, std::vector<ISCH_SCHEMA_PAGE>& _schema)
  29. {
  30. const std::vector<schema::SCHEMA_QUESTION> &questions =schema.questions;
  31. _schema.resize(schema.pages.size());
  32. for (int i=0;i<schema.pages.size();i++)
  33. {
  34. const SCHEMA_PAGE& schema_page=schema.pages[i];
  35. /************************************************************************/
  36. /* 整理模板到结果中 */
  37. /************************************************************************/
  38. ISCH_SCHEMA_PAGE* page = &_schema[i];
  39. SetPageDefault(*page);
  40. page->index = i;
  41. page->width =schema_page.width;
  42. page->height =schema_page.height;
  43. page->locatePoints.resize(schema_page.locatePoints.size());
  44. for (int idx_i = 0; idx_i < schema_page.locatePoints.size(); idx_i++)
  45. {
  46. identify::schema::ISCH_SCHEMA_LOCATE_POINT& dst = page->locatePoints[idx_i];
  47. const schema::SCHEMA_LOCATE_POINT& src = schema_page.locatePoints[idx_i];
  48. dst.centerx = src.centerx;
  49. dst.centery = src.centery;
  50. dst.width = src.width;
  51. dst.height = src.height;
  52. dst.nID = src.nID;
  53. }
  54. page->locateCrosses.resize(schema_page.locateCrosses.size());
  55. for (int idx_i = 0; idx_i < schema_page.locateCrosses.size(); idx_i++)
  56. {
  57. identify::schema::ISCH_SCHEMA_LOACTE_CROSS& dst = page->locateCrosses[idx_i];
  58. const schema::SCHEMA_LOACTE_CROSS& src = schema_page.locateCrosses[idx_i];
  59. dst.centerx = src.centerx;
  60. dst.centery = src.centery;
  61. dst.width = src.width;
  62. dst.height = src.height;
  63. dst.nID = src.nID;
  64. dst.angle = src.angle;
  65. dst.sign = src.sign;
  66. }
  67. page->codes.resize(schema_page.codes.size());
  68. for (int idx_i = 0; idx_i < schema_page.codes.size(); idx_i++)
  69. {
  70. identify::schema::ISCH_SCHEMA_CODE& dst = page->codes[idx_i];
  71. const schema::SCHEMA_CODE& src = schema_page.codes[idx_i];
  72. dst.centerx = src.centerx;
  73. dst.centery = src.centery;
  74. dst.width = src.width;
  75. dst.height = src.height;
  76. dst.nID = src.nID;
  77. dst.bDirection = (identify::schema::ISCH_DIRECTION)(int)src.bDirection;
  78. }
  79. page->cutAreas.resize(schema_page.clips.size());
  80. for (int idx_i = 0; idx_i < schema_page.clips.size(); idx_i++)
  81. {
  82. identify::schema::ISCH_SCHEMA_CLIP& dst = page->cutAreas[idx_i];
  83. const schema::SCHEMA_CLIP& src = schema_page.clips[idx_i];
  84. dst.centerx = src.centerx;
  85. dst.centery = src.centery;
  86. dst.width = src.width;
  87. dst.height = src.height;
  88. dst.nID = src.nID;
  89. dst.area_name = src.area_name;
  90. dst.markUnit = src.markUnit;
  91. dst.markUnitPart = src.markUnitPart;
  92. }
  93. Mat img = imread(img_paths[i],CV_LOAD_IMAGE_GRAYSCALE);
  94. double angle =schema_page.angle;
  95. double a = fmod(fmod(angle,360)+360,360);
  96. int nWidth,nHeight;
  97. if((a>45&&a<=135)||(a>45+180&&a<=135+180)){
  98. nHeight = img.cols;
  99. nWidth = img.rows;
  100. }else{
  101. nWidth = img.cols;
  102. nHeight = img.rows;
  103. }
  104. page->width = nWidth;
  105. page->height = nHeight;
  106. double sina = sin(CV_PI*angle/180);
  107. double cosa = cos(CV_PI*angle/180);
  108. CvPoint2D32f center0 = cvPoint2D32f(img.cols/2.0,img.rows/2.0);
  109. CvPoint2D32f center1 = cvPoint2D32f(nWidth/2.0,nHeight/2.0);
  110. float offsetx = center1.x - (cosa*center0.x+sina*center0.y);
  111. float offsety = center1.y - (-sina*center0.x+cosa*center0.y);
  112. float data[6]={cosa,sina,offsetx,-sina,cosa,offsety};
  113. Mat m(2,3,CV_32F,data);
  114. Mat img_rotated;
  115. warpAffine(img,img_rotated,m,cvSize(nWidth,nHeight));
  116. img.release();
  117. IplImage * img_smoothd = &IplImage(img_rotated);
  118. cvSmooth(img_smoothd, img_smoothd, CV_GAUSSIAN, 5);
  119. caculateLocateArea(img_rotated,schema_page.locateAreas,page->locateAreas);
  120. }
  121. }
  122. ServiceState CLocateTester::OnRunning( void )
  123. {
  124. const int rotation[4]={ROTATION_0,ROTATION_90,ROTATION_180,ROTATION_270};
  125. m_matchtask.resize(imgs.size()*_schema->size()*4);
  126. for (int idx_img=0,idx_task=0;idx_img<imgs.size();idx_img++){
  127. for (int idx_schema=0;idx_schema<_schema->size();idx_schema++)
  128. {
  129. for(int idx_dir=0;idx_dir<4;idx_dir++){
  130. for(bool disptch_failture=true;disptch_failture;){
  131. for (int idx_worker=0;disptch_failture&&idx_worker<WORKER_COUNT;idx_worker++)
  132. {
  133. if(m_worker[idx_worker].isBusy())continue;
  134. CTestMatchTask match_task(imgs[idx_img],&matcher[idx_worker],idx_schema,rotation[idx_dir]);
  135. m_matchtask[idx_task] =match_task;
  136. m_worker[idx_worker].addTask(&m_matchtask[idx_task]);
  137. disptch_failture=false;
  138. idx_task++;
  139. }
  140. if(disptch_failture){Sleep(1);}
  141. }
  142. }
  143. }
  144. }
  145. for (;;){
  146. bool someone_busy =false;
  147. for (int idx_worker=0;idx_worker<WORKER_COUNT;idx_worker++)
  148. {
  149. if(m_worker[idx_worker].isBusy()){someone_busy =true;break;}
  150. }
  151. if(someone_busy){Sleep(10);}else{break;}
  152. }
  153. bool isOk =true;
  154. std::string msg;
  155. for (int idx_img=0,idx_task=0,error_page_count=0;idx_img<imgs.size();idx_img++){
  156. int schema_match_task_idx =-1;
  157. int schema_match_schema_idx =-1;
  158. bool schema_mutil_dir_matched=false ;
  159. bool schema_mutil_page_matched=false;
  160. for (int idx_schema=0;idx_schema<_schema->size();idx_schema++){
  161. int dir_match_task_idx=-1;
  162. bool dir_mutil_dir_matched=false;
  163. for(int idx_dir=0;idx_dir<4;idx_dir++,idx_task++){
  164. if(m_matchtask[idx_task].result.matched){
  165. if(dir_match_task_idx<0||m_matchtask[idx_task].result.matched_count>m_matchtask[dir_match_task_idx].result.matched_count){
  166. dir_match_task_idx =idx_task;
  167. }
  168. if(dir_match_task_idx>=0&&dir_match_task_idx!=idx_task&&m_matchtask[idx_task].result.matched_count==m_matchtask[dir_match_task_idx].result.matched_count){
  169. dir_mutil_dir_matched=true;
  170. }
  171. }
  172. }
  173. if(dir_match_task_idx>=0){
  174. if(schema_match_schema_idx<0){
  175. schema_match_task_idx =dir_match_task_idx;
  176. schema_match_schema_idx = idx_schema;
  177. schema_mutil_dir_matched =dir_mutil_dir_matched;
  178. schema_mutil_page_matched =false;
  179. }else{
  180. int gailv1 =m_matchtask[schema_match_task_idx].result.matched_count*2-m_matchtask[schema_match_task_idx].result.total_count;
  181. int gailv2 =m_matchtask[dir_match_task_idx].result.matched_count*2-m_matchtask[dir_match_task_idx].result.total_count;
  182. if(gailv1<gailv2){
  183. schema_match_task_idx=dir_match_task_idx;
  184. schema_match_schema_idx=idx_schema;
  185. schema_mutil_dir_matched =dir_mutil_dir_matched;
  186. schema_mutil_page_matched =false;
  187. }else if(gailv1==gailv2){
  188. schema_mutil_page_matched= true;
  189. }
  190. }
  191. }
  192. }
  193. char msg0[512];
  194. if(idx_img==schema_match_schema_idx&&!schema_mutil_page_matched&&!schema_mutil_dir_matched){
  195. sprintf_s(msg0,"第%d页正常识别",idx_img+1);
  196. }else{
  197. if(isOk)isOk =false;
  198. if(schema_match_schema_idx<0){sprintf_s(msg0,"第%d页无法正确对应模板进行匹配,请重新设置定位点",idx_img+1);}
  199. else if(idx_img!=schema_match_schema_idx){sprintf_s(msg0,"第%d页无法匹配上对应页的模板,请重新设置定位点",idx_img+1);}
  200. else if(schema_mutil_page_matched&&schema_mutil_dir_matched)sprintf_s(msg0,"第%d页可以与多页的多个方向进行匹配,请重新设置定位点",idx_img+1);
  201. else if(schema_mutil_page_matched)sprintf_s(msg0,"第%d页可以与多页进行匹配,请重新设置定位点",idx_img+1);
  202. else if(schema_mutil_dir_matched)sprintf_s(msg0,"第%d页可以多个方向进行匹配,请重新设置定位点",idx_img+1);
  203. if(error_page_count>0)msg.append(",");
  204. msg.append(msg0);
  205. }
  206. }
  207. m_isOk =isOk;
  208. m_error_msg=msg;
  209. m_isResultOk =true;
  210. return ServiceState::stoping;
  211. }
  212. ServiceState CLocateTester::OnStarting( void )
  213. {
  214. for (int idx_worker=0;idx_worker<WORKER_COUNT;idx_worker++)
  215. {
  216. if(m_worker[idx_worker].GetServiceSate()==ServiceState::stoped){
  217. m_worker[idx_worker].Start();
  218. }
  219. }
  220. bool all_running;
  221. do
  222. {
  223. all_running=true;
  224. for (int idx_worker=0;idx_worker<WORKER_COUNT;idx_worker++)
  225. {
  226. if(m_worker[idx_worker].GetServiceSate()!=ServiceState::running){
  227. all_running=false;
  228. }
  229. }
  230. if(!all_running){Sleep(10);}
  231. } while (!all_running);
  232. return ServiceState::running;
  233. }
  234. bool CLocateTester::test( const schema::SCHEMA& schema,const std::vector<std::string>& img_paths )
  235. {
  236. if(isSameLocateSchema(schema))return true;
  237. m_isReady = false;
  238. m_isResultOk = false;
  239. last_test_schema = schema;
  240. for (int i=0;i<img_paths.size();i++)
  241. {
  242. imgs.push_back(imread(img_paths[i],CV_LOAD_IMAGE_GRAYSCALE));
  243. }
  244. loadSchema(last_test_schema,img_paths,*_schema);
  245. for(int idx_i=0;idx_i<WORKER_COUNT;idx_i++){
  246. matcher[idx_i].SetSchemaPages(_schema);
  247. }
  248. Start();
  249. return true;
  250. }
  251. bool CLocateTester::isSameLocateSchema( const schema::SCHEMA& schema )
  252. {
  253. bool isSame =true;
  254. if(schema.pages.size() == last_test_schema.pages.size()){
  255. for (int idx_page =0;isSame&&idx_page <schema.pages.size();idx_page++)
  256. {
  257. const SCHEMA_PAGE& pages1 =schema.pages[idx_page];
  258. const SCHEMA_PAGE& pages0 =last_test_schema.pages[idx_page];
  259. if(pages1.nID == pages0.nID&&pages1.angle == pages0.angle
  260. &&pages1.locatePoints.size()==pages0.locatePoints.size()
  261. &&pages1.locateAreas.size()==pages0.locateAreas.size()
  262. &&pages1.locateCrosses.size()==pages0.locateCrosses.size()){
  263. for (int idx_l=0;isSame&&idx_l<pages0.locatePoints.size();idx_l++)
  264. {
  265. if(pages0.locatePoints[idx_l].centerx!=pages1.locatePoints[idx_l].centerx
  266. ||pages0.locatePoints[idx_l].centery!=pages1.locatePoints[idx_l].centery
  267. ||pages0.locatePoints[idx_l].width!=pages1.locatePoints[idx_l].width
  268. ||pages0.locatePoints[idx_l].height!=pages1.locatePoints[idx_l].height){
  269. isSame=false;
  270. break;
  271. }
  272. }
  273. for (int idx_l=0;isSame&&idx_l<pages0.locateAreas.size();idx_l++)
  274. {
  275. if(pages0.locateAreas[idx_l].centerx!=pages1.locateAreas[idx_l].centerx
  276. ||pages0.locateAreas[idx_l].centery!=pages1.locateAreas[idx_l].centery
  277. ||pages0.locateAreas[idx_l].width!=pages1.locateAreas[idx_l].width
  278. ||pages0.locateAreas[idx_l].height!=pages1.locateAreas[idx_l].height){
  279. isSame=false;
  280. break;
  281. }
  282. }
  283. for (int idx_l=0;isSame&&idx_l<pages0.locateCrosses.size();idx_l++)
  284. {
  285. if(pages0.locateCrosses[idx_l].centerx!=pages1.locateCrosses[idx_l].centerx
  286. ||pages0.locateCrosses[idx_l].centery!=pages1.locateCrosses[idx_l].centery
  287. ||pages0.locateCrosses[idx_l].width!=pages1.locateCrosses[idx_l].width
  288. ||pages0.locateCrosses[idx_l].height!=pages1.locateCrosses[idx_l].height){
  289. isSame=false;
  290. break;
  291. }
  292. }
  293. }else{
  294. isSame=false;
  295. break;
  296. }
  297. }
  298. }else{
  299. isSame=false;
  300. }
  301. return isSame;
  302. }
  303. ServiceState CLocateTester::OnStoping( void )
  304. {
  305. _schema->clear();
  306. for (int idx_worker=0;idx_worker<WORKER_COUNT;idx_worker++)
  307. {
  308. if(m_worker[idx_worker].GetServiceSate()!=ServiceState::stoped){
  309. m_worker[idx_worker].Stop();
  310. }
  311. }
  312. imgs.clear();
  313. m_isReady = true;
  314. return IService::OnStoping();
  315. }
  316. bool CLocateTester::isReady()
  317. {
  318. return m_isReady;
  319. }