ECOMCalibration.cpp 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071
  1. #include "stdafx.h"
  2. #include "ZSKKCalibration.h"
  3. using std::string;
  4. CZSKKCalibrationCtrl::CZSKKCalibrationCtrl()
  5. {
  6. m_nGridSuppressed = 0;
  7. m_nFullImgWidth = 0;
  8. m_nFullImgHeight = 0;
  9. m_nHeightOffset = 0;
  10. m_nWidthOffset = 0;
  11. m_bAutoBadPixel = true;
  12. m_nReferenceNum = 3;
  13. m_nSaveRawDataMode = 0;
  14. m_strRawImgPath = ".\\";
  15. m_strRefFilePath = ".\\";
  16. m_nSaturationValue = 50000;
  17. m_pZSKKGainMatrix = NULL;
  18. m_pZSKKPixMatrix = NULL;
  19. }
  20. CZSKKCalibrationCtrl::~CZSKKCalibrationCtrl()
  21. {
  22. if (m_pZSKKGainMatrix != NULL)
  23. {
  24. delete m_pZSKKGainMatrix;
  25. m_pZSKKGainMatrix = NULL;
  26. }
  27. if (m_pZSKKPixMatrix != NULL)
  28. {
  29. delete m_pZSKKPixMatrix;
  30. m_pZSKKPixMatrix = NULL;
  31. }
  32. }
  33. //去栅影
  34. bool CZSKKCalibrationCtrl::GridSuppressed(int nHeight, int nWidth, unsigned short* pImage)
  35. {
  36. //logfile->WriteLog("Process Grid Suppression...", LOG_INFORMATION, LOG_DEBUG, true);
  37. if (pImage == NULL)
  38. {
  39. //logfile->WriteLog("the image buffer is Null.", LOG_ERROR, LOG_DEBUG, true);
  40. return false;
  41. }
  42. bool bResult = false;
  43. //CString strLog;
  44. //strLog.Format("Current Grid Suppressed: %d", m_nGridSuppressed);
  45. //logfile->WriteLog(strLog, LOG_INFORMATION, LOG_DEBUG, true);
  46. if (m_nGridSuppressed == 2)
  47. {
  48. //logfile->WriteLog("Manual: No Grid", LOG_INFORMATION, LOG_DEBUG, true);
  49. return false;
  50. }
  51. if (m_pZSKKPixMatrix)
  52. {
  53. GridBadLineCorrectFirst(nHeight, nWidth, pImage);
  54. }
  55. try
  56. {
  57. int nGridDirection = GridSuppression_US(pImage, nWidth, nHeight, m_nGridSuppressed);
  58. //m_nGridDirction = nGridDirection;
  59. switch (nGridDirection)
  60. {
  61. case 1:
  62. //logfile->WriteLog("Process Vertical Grid Over", LOG_INFORMATION, LOG_DEBUG, true);
  63. bResult = true;
  64. //*pnGridDirection = 1;
  65. break;
  66. case 2:
  67. //logfile->WriteLog("Process Horizontal Grid Over", LOG_INFORMATION, LOG_DEBUG, true);
  68. bResult = true;
  69. //*pnGridDirection = 2;
  70. break;
  71. case 0:
  72. //logfile->WriteLog("No Grid Detected", LOG_INFORMATION, LOG_DEBUG, true);
  73. break;
  74. case -1:
  75. //logfile->WriteLog("The image size is wrong", LOG_WARNING, LOG_DEBUG, true);
  76. break;
  77. default:
  78. //logfile->WriteLog("Unknown Error", LOG_WARNING, LOG_DEBUG, true);
  79. break;
  80. }
  81. if (m_pZSKKPixMatrix)
  82. {
  83. if ((nGridDirection == 1) || (nGridDirection == 2))
  84. {
  85. //LogInfo("Begin to Correct Bad Line");
  86. if (m_pZSKKPixMatrix)
  87. {
  88. m_pZSKKPixMatrix->LoadandCorrectBadLine(pImage, nGridDirection);
  89. //LogInfo("Correct Bad Line Over");
  90. }
  91. else
  92. {
  93. //LogError("Correct Bad Line Failed,No Bad File Map");
  94. }
  95. }
  96. GridBadLineCorrectSecond(nHeight, nWidth, pImage);
  97. }
  98. }
  99. catch (...)
  100. {
  101. //LogError("GridSuppression Function is Crash,please Recover Last Image or Not");
  102. }
  103. return bResult;
  104. }
  105. bool CZSKKCalibrationCtrl::GridBadLineCorrectFirst(int nHeight, int nWidth, unsigned short* pImage)
  106. {
  107. //CString strLog = "";
  108. //LogInfo("Begin to Grid Judgement");
  109. int nGridExist = GridJudgement(pImage, nWidth, nHeight, m_nGridSuppressed);
  110. if (nGridExist > 0) //有栅的情况
  111. {
  112. //strLog.Format("Grid Judgement Result:%d", nGridExist);
  113. //LogInfo(strLog);
  114. if (m_pZSKKPixMatrix)
  115. {
  116. int nDefectType = 0;
  117. //只对平行于栅影的坏线处理,2016.07.21 ,zhaoyiru
  118. if (1 == nGridExist) //竖直栅影
  119. {
  120. for (int i = 0; i < m_pZSKKPixMatrix->m_nLineData; i = i + 4)
  121. {
  122. if (-1 == m_pZSKKPixMatrix->m_datalen[i])
  123. {
  124. break;
  125. }
  126. if (0 == m_pZSKKPixMatrix->m_datalen[i]) //水平坏线
  127. {
  128. nDefectType = 1;
  129. int nRtn = m_pZSKKPixMatrix->BadGridLineCorrect1(pImage, m_pZSKKPixMatrix->m_datalen[i], m_pZSKKPixMatrix->m_datalen[i + 1],
  130. m_pZSKKPixMatrix->m_datalen[i + 2], m_pZSKKPixMatrix->m_datalen[i + 3], nWidth, nHeight);
  131. }
  132. if (1 == m_pZSKKPixMatrix->m_datalen[i]) //竖直坏线
  133. {
  134. nDefectType += 2;
  135. int nRtn = m_pZSKKPixMatrix->BadGridLineCorrect2(pImage, m_pZSKKPixMatrix->m_datalen[i], m_pZSKKPixMatrix->m_datalen[i + 1],
  136. m_pZSKKPixMatrix->m_datalen[i + 2], m_pZSKKPixMatrix->m_datalen[i + 3], nWidth, nHeight);
  137. }
  138. }
  139. }
  140. else if (2 == nGridExist) //水平栅影
  141. {
  142. for (int i = 0; i < m_pZSKKPixMatrix->m_nLineData; i = i + 4)
  143. {
  144. if (-1 == m_pZSKKPixMatrix->m_datalen[i])
  145. {
  146. break;
  147. }
  148. if (0 == m_pZSKKPixMatrix->m_datalen[i]) //水平坏线
  149. {
  150. nDefectType = 1;
  151. int nRtn = m_pZSKKPixMatrix->BadGridLineCorrect1(pImage, m_pZSKKPixMatrix->m_datalen[i], m_pZSKKPixMatrix->m_datalen[i + 1],
  152. m_pZSKKPixMatrix->m_datalen[i + 2], m_pZSKKPixMatrix->m_datalen[i + 3], nWidth, nHeight);
  153. }
  154. if (1 == m_pZSKKPixMatrix->m_datalen[i]) //竖直坏线
  155. {
  156. nDefectType += 2;
  157. int nRtn = m_pZSKKPixMatrix->BadGridLineCorrect2(pImage, m_pZSKKPixMatrix->m_datalen[i], m_pZSKKPixMatrix->m_datalen[i + 1],
  158. m_pZSKKPixMatrix->m_datalen[i + 2], m_pZSKKPixMatrix->m_datalen[i + 3], nWidth, nHeight);
  159. }
  160. }
  161. }
  162. if (nDefectType == 0)
  163. {
  164. //LogInfo("No defect lines");
  165. }
  166. else if (nDefectType == 1)
  167. {
  168. //LogInfo("Horizontal defect lines");
  169. }
  170. else if (nDefectType % 2 == 0)
  171. {
  172. //LogInfo("Vertical defect lines");
  173. }
  174. else if (nDefectType % 2 == 1)
  175. {
  176. //LogInfo("Both direction defect lines");
  177. }
  178. //if ((1 == nGridExist) || (2 == nGridExist))
  179. //{
  180. // //LogInfo("Switch DoubleBadLines");
  181. // m_pZSKKPixMatrix->SwitchDBadLines(pImage);
  182. // if (m_nSaveRawDataMode != 0)
  183. // {
  184. // if (!SaveImage(pImage, "Image_DoubleBadLinePrep.raw", nHeight, nWidth))
  185. // {
  186. // LogError("Save DBadline Prep Image File Failed");
  187. // }
  188. // else
  189. // {
  190. // LogInfo("Save DBadline Prep Image File Over");
  191. // }
  192. // }
  193. //}
  194. return true;
  195. }
  196. else
  197. {
  198. //LogWarn("ZSKK PixMatrix is NULL");
  199. return false;
  200. }
  201. }
  202. else
  203. {
  204. //LogInfo("Grid Judgemet Result:No gird");
  205. return false;
  206. }
  207. }
  208. bool CZSKKCalibrationCtrl::GridBadLineCorrectSecond(int nHeight, int nWidth, unsigned short* pImage)
  209. {
  210. if (m_pZSKKPixMatrix != NULL)
  211. {
  212. // 对水平竖直坏线分别处理
  213. int nDefectType = 0;
  214. for (int i = 0; i < m_pZSKKPixMatrix->m_nLineData; i = i + 4)
  215. {
  216. if (-1 == m_pZSKKPixMatrix->m_datalen[i])
  217. {
  218. break;
  219. }
  220. if (1 == m_pZSKKPixMatrix->m_datalen[i]) //竖直坏线
  221. {
  222. nDefectType = 1;
  223. int nlbadlineRet = 0;
  224. nlbadlineRet = m_pZSKKPixMatrix->BadGridLineCorrect4(pImage, m_pZSKKPixMatrix->m_datalen[i], m_pZSKKPixMatrix->m_datalen[i + 1],
  225. m_pZSKKPixMatrix->m_datalen[i + 2], m_pZSKKPixMatrix->m_datalen[i + 3], nWidth, nHeight);
  226. }
  227. if (0 == m_pZSKKPixMatrix->m_datalen[i]) //水平坏线
  228. {
  229. nDefectType += 2;
  230. int nlbadlineRet = 0;
  231. nlbadlineRet = m_pZSKKPixMatrix->BadGridLineCorrect3(pImage, m_pZSKKPixMatrix->m_datalen[i], m_pZSKKPixMatrix->m_datalen[i + 1],
  232. m_pZSKKPixMatrix->m_datalen[i + 2], m_pZSKKPixMatrix->m_datalen[i + 3], nWidth, nHeight);
  233. }
  234. }
  235. /*if (nDefectType == 0)
  236. {
  237. LogInfo("No defect lines");
  238. }
  239. else if (nDefectType == 1)
  240. {
  241. LogInfo("Vertical defect lines");
  242. }
  243. else if (nDefectType % 2 == 0)
  244. {
  245. LogInfo("Horizontal defect lines");
  246. }
  247. else if (nDefectType % 2 == 1)
  248. {
  249. LogInfo("Both direction defect lines");
  250. }
  251. if ((nDefectType != 0) && (m_nSaveRawDataMode != 0))
  252. {
  253. if (!SaveImage(pImage, "Image_BadLinePost.raw", nHeight, nWidth))
  254. {
  255. LogError("Save Grid badline Post Image File Failed");
  256. }
  257. else
  258. {
  259. LogInfo("Save Grid badline Post Image File Over");
  260. }
  261. }*/
  262. ApplyZSKKLineMap(pImage);
  263. return true;
  264. }
  265. else
  266. {
  267. //LogWarn("ZSKK PixMatrix is NULL");
  268. return false;
  269. }
  270. }
  271. //生成新的full map
  272. //[IN]: 图像高度
  273. //[IN]:文件路径和名称
  274. bool CZSKKCalibrationCtrl::CreateEmptyMap(int nHeight, const char* pcRefPath)
  275. {
  276. //Fill the map file
  277. char* pMapData = new char[nHeight * 10];
  278. if (NULL == pMapData)
  279. {
  280. //logfile->WriteLog("Failed to allocate memory", LOG_ERROR, LOG_DEBUG, true);
  281. return false;
  282. }
  283. memset(pMapData, 0, nHeight * 10 * sizeof(char));
  284. int nCharCount = 0;
  285. for (int nRow = 0; nRow < nHeight; nRow++)
  286. {
  287. if (nCharCount >= (nHeight - 2) * 10)
  288. {
  289. break;
  290. }
  291. int nLength = sprintf(pMapData + nCharCount, "%d,0:\n", nRow);//need to modify
  292. nCharCount += nLength;
  293. }
  294. //record the buffer size
  295. int nBufferSize = nHeight * 10 * sizeof(char);
  296. /*CString strLog;
  297. strLog.Format("the allocated buffer size is %d", nBufferSize);
  298. LogInfo(strLog);*/
  299. //write data to file
  300. FILE* pFile = NULL;
  301. pFile = fopen(pcRefPath, "wb");
  302. if (static_cast<int>(fwrite(pMapData, 1, nCharCount, pFile)) != nCharCount)
  303. {
  304. /*TRACE("Failed to write map");
  305. logfile->WriteLog("Failed to write the defect map th hard disk", LOG_ERROR, LOG_DEBUG, true);*/
  306. return false;
  307. }
  308. fclose(pFile);
  309. if (pMapData != NULL)
  310. {
  311. delete[] pMapData;
  312. pMapData = NULL;
  313. }
  314. return true;
  315. }
  316. //int CZSKKCalibrationCtrl::JudgeDarkImage(WORD* pOldData, WORD* pNewData, int nWidth, int nHeight)
  317. //{
  318. // logfile->WriteLog("Judging Dark Image", LOG_INFORMATION, LOG_DEBUG, true);
  319. //
  320. // int m_nDarkImageCheck = 1;
  321. // if (!m_nDarkImageCheck)
  322. // {
  323. // return 0;
  324. // }
  325. // int nReturn = DarkImageJudge(pOldData, pNewData, nWidth, nHeight, 200, 5);
  326. //
  327. // if (nReturn >= 0)
  328. // {
  329. // logfile->WriteLog("Dark Image is valid", LOG_INFORMATION, LOG_DEBUG, true);
  330. // return 1;
  331. // }
  332. // else
  333. // {
  334. // logfile->WriteLog("Dark Image is Invalid", LOG_ERROR, LOG_DEBUG, true);
  335. // return -1;
  336. // }
  337. //}
  338. //int CZSKKCalibrationCtrl::JudgeWhiteImage(WORD* pwData, int nWidth, int nHeight, int nWidthOffset, int nHeightOffset, unsigned short nCurrentTargetDV)
  339. //{
  340. // int m_nWhiteImageCheck = 1;
  341. // if (!m_nWhiteImageCheck)
  342. // {
  343. // return -5;
  344. // }
  345. // else
  346. // {
  347. // int nReturn = FlatImageCheck(pwData, nWidth, nHeight, nWidthOffset, nHeightOffset, nCurrentTargetDV, 0.1f, 0.2f, 0.1f);
  348. // CString strLog;
  349. // strLog.Format("The returned value of FlatImageCheck function is %d", nReturn);
  350. // logfile->WriteLog(strLog, LOG_INFORMATION, LOG_DEBUG, true);
  351. // if (nReturn >= 0)//correct
  352. // {
  353. // logfile->WriteLog("The flat image is able to use!", LOG_INFORMATION, LOG_DEBUG, true);
  354. // return 1;
  355. // }
  356. // else if (nReturn == -1)// the average dv are more or less than 10 percent of the predefined value
  357. // {
  358. // logfile->WriteLog("The average pixel value is out of the range of the target value", LOG_WARNING, LOG_DEBUG, true);
  359. // //::PostMessage(this->m_hWnd,MSG_PANEL_STATUS,PNL_READY,NULL);
  360. // return -1;
  361. // }
  362. // else if (nReturn == -2)// not flat
  363. // {
  364. // logfile->WriteLog("The image is not flat", LOG_WARNING, LOG_DEBUG, true);
  365. // //::PostMessage(this->m_hWnd,MSG_PANEL_STATUS,PNL_READY,NULL);
  366. // return -2;
  367. //
  368. // }
  369. // else//wrong
  370. // {
  371. // logfile->WriteLog("The flat image is invalid!", LOG_WARNING, LOG_DEBUG, true);
  372. // return -3;
  373. // }
  374. // }
  375. //}
  376. //method to reset gain calibration process object;
  377. bool CZSKKCalibrationCtrl::CreateGainMatrix(CGainMatrix* pGainMatrix, int nWidth, int nHeight, int nWidthOffset, int nHeightOffset, int nRefrenceNum, WORD wMaxPv)
  378. {
  379. //destroy object before;
  380. if (NULL != pGainMatrix)
  381. {
  382. delete pGainMatrix;
  383. pGainMatrix = NULL;
  384. }
  385. //create new object;
  386. pGainMatrix = new CGainMatrix(nWidth, nHeight, nWidthOffset, nHeightOffset, nRefrenceNum, wMaxPv);
  387. if (pGainMatrix == NULL)
  388. {
  389. return false;
  390. }
  391. bool m_bGainMAPReady = true;
  392. if (NULL != pGainMatrix)
  393. {
  394. for (size_t nIndex = 0; nIndex < nRefrenceNum; nIndex++)
  395. {
  396. //CString strFileName;
  397. //strFileName.Format("%s\\TETD_Gain_%d_%d.cal", m_strReferencePath, m_panelXmlStruct.nPanelGainMode, nIndex);
  398. string strFileName = "TETD_Gain_.cal";
  399. if (!pGainMatrix->LoadGainMap(strFileName.c_str()))
  400. {
  401. //logfile->WriteLog("Fail to load gain map!", LOG_WARNING, LOG_DEBUG, true);
  402. m_bGainMAPReady = false;
  403. break;
  404. }
  405. }
  406. if (!m_bGainMAPReady)
  407. {
  408. delete pGainMatrix;
  409. pGainMatrix = NULL;
  410. }
  411. }
  412. else
  413. {
  414. //logfile->WriteLog("Failed to allocate memory", LOG_ERROR, LOG_DEBUG, true);
  415. return false;
  416. }
  417. return m_bGainMAPReady;
  418. }
  419. bool CZSKKCalibrationCtrl::BeginGainCalibration(CGainMatrix* pGainMatrix, int nWidth, int nHeight, int nWidthOffset, int nHeightOffset, int nRefrenceNum, WORD wMaxPv)
  420. {
  421. if (pGainMatrix)
  422. {
  423. delete pGainMatrix;
  424. }
  425. pGainMatrix = new CGainMatrix(nWidth, nHeight, nWidthOffset, nHeightOffset, nRefrenceNum, wMaxPv);
  426. if (pGainMatrix == NULL)
  427. {
  428. return false;
  429. }
  430. for (int i = 0; i < nRefrenceNum; i++)
  431. {
  432. if (!pGainMatrix->LoadGainMap())
  433. {
  434. return false;
  435. }
  436. }
  437. return true;
  438. }
  439. /************************************************************************************
  440. 预处理模块调用示例:
  441. 初始化探测器InitPanel
  442. LoadZSKKGainMap()
  443. LoadZSKKPixelMap()
  444. LoadZSKKLineMap()
  445. 退出探测器ExitPanel
  446. UnLoadZSKKGainMap()
  447. UnLoadZSKKPixMap()
  448. 图像校正OnTransImgEnd
  449. ApplyZSKKGainMap(pImage)
  450. ApplyZSKKPixMap(pImage)
  451. ApplyZSKKLineMap(pImage)
  452. 开始探测器校正StartCalibration
  453. LoadZSKKGainMap(false)
  454. LoadZSKKPixelMap(false)
  455. 中止探测器校正
  456. LoadZSKKGainMap()
  457. AbortZSKKPixMap()
  458. 接受当前探测器校正图像
  459. AverageZSKKGainMap(pImage)
  460. AddImageToPixMap(pImage)
  461. 完成探测器校正
  462. StoreZSKKGainMap()
  463. StoreZSKKPixMap()
  464. ************************************************************************************/
  465. /************************************************************************************
  466. 功能:当bInit为true时,应用于初始化探测器时加载增益校正文件,
  467. 磁盘中增益校正文件不存在时,删除该实例m_pZSKKGainMatrix;
  468. 当bInit为false时,应用于开始探测器增益校正时候,
  469. 重新分配增益校正内存,忽略磁盘中的校正文件。
  470. 注意:两个LoadGainMap的形参不同,作用不同。
  471. 参数:m_nWidth为有效区域图像的宽度;
  472. m_nHeight为有效区域图像的高度;
  473. m_nSaturationValue为图像灰度的饱和值
  474. m_nReferenceNum为需要进行校正的点数
  475. m_vectorCalMode[0]为配置文件<ProcContent>内容
  476. ************************************************************************************/
  477. bool CZSKKCalibrationCtrl::LoadZSKKGainMap(bool bInit, string strSerial)
  478. {
  479. //LogInfo("Load ZSKK Gain Cal File");
  480. //destroy object before;
  481. if (m_pZSKKGainMatrix)
  482. {
  483. delete m_pZSKKGainMatrix;
  484. m_pZSKKGainMatrix = NULL;
  485. }
  486. /*CString str;
  487. str.Format("FullImgWidth [%d],FullImgHeight [%d],SaturationValue [%d]", m_nFullImgWidth, m_nFullImgHeight, m_nSaturationValue);
  488. LogInfo(str);*/
  489. m_pZSKKGainMatrix = new CGainMatrix(m_nFullImgWidth, m_nFullImgHeight, 0, 0, m_nReferenceNum, m_nSaturationValue);//m_nReferenceNum
  490. if (NULL == m_pZSKKGainMatrix)
  491. {
  492. //LogError("ZSKKGainMatrix Allocate Failed");
  493. return false;
  494. }
  495. bool bRtn = true;
  496. //CString strFile;
  497. //CString strtemp = strGain + m_vectorCalMode[0];
  498. //LogInfo(strtemp);
  499. string strGainFileName;
  500. if (bInit)
  501. {
  502. for (int i = 0; i < m_nReferenceNum; i++)
  503. {
  504. //strFile.Format("%s\\%s_%d.cal", m_strRefFilePath, strtemp, i);
  505. strGainFileName = m_strRefFilePath + strSerial + "_" + std::to_string(i) + ".cal";
  506. if (!m_pZSKKGainMatrix->LoadGainMap(strGainFileName.c_str()))
  507. {
  508. //LogError("Fail to Load gain Map");
  509. bRtn = false;
  510. break;
  511. }
  512. /*else
  513. {
  514. LogInfo(strFile);
  515. }*/
  516. }
  517. }
  518. else
  519. {
  520. for (int i = 0; i < m_nReferenceNum; i++)
  521. {
  522. if (!m_pZSKKGainMatrix->LoadGainMap())
  523. {
  524. bRtn = false;
  525. break;
  526. }
  527. }
  528. }
  529. if (!bRtn)
  530. {
  531. delete m_pZSKKGainMatrix;
  532. m_pZSKKGainMatrix = NULL;
  533. }
  534. return bRtn;
  535. }
  536. bool CZSKKCalibrationCtrl::UnLoadZSKKGainMap()
  537. {
  538. if (m_pZSKKGainMatrix)
  539. {
  540. delete m_pZSKKGainMatrix;
  541. m_pZSKKGainMatrix = NULL;
  542. }
  543. return true;
  544. }
  545. /************************************************************************************
  546. 功能:应用于图像的增益校正
  547. 当m_nSaveRawDataMode不为0时,保存校正后的图像数据到rawdata\AfterGain.raw文件中。
  548. 参数:pImage为输入的原始图像数据,应用图像增益校正后,输出校正后的图像数据。
  549. ************************************************************************************/
  550. bool CZSKKCalibrationCtrl::ApplyZSKKGainMap(WORD* pImage)
  551. {
  552. if (NULL == m_pZSKKGainMatrix || NULL == pImage)
  553. {
  554. return false;
  555. }
  556. bool bRtn = true;
  557. //LogInfo("Apply Gain Correction");
  558. m_pZSKKGainMatrix->ApplyGainMap(pImage);
  559. if (m_nSaveRawDataMode != 0)
  560. {
  561. if (!SaveRawImage("Image_AfterGain.raw", pImage, m_nFullImgWidth, m_nFullImgHeight))
  562. {
  563. //bRtn = false;
  564. }
  565. else
  566. {
  567. //bRtn = true;
  568. }
  569. }
  570. //LogInfo("Apply Gain Correction Over");
  571. return true;
  572. }
  573. /************************************************************************************
  574. 功能:输入用于探测器增益校正使用的原始图像数据
  575. 参数:pImage为输入的原始图像数据
  576. ************************************************************************************/
  577. bool CZSKKCalibrationCtrl::AverageZSKKGainMap(WORD* wImage, int nRefIndex, bool bStart)
  578. {
  579. //("Average Gain Map");
  580. if (NULL != m_pZSKKGainMatrix)
  581. {
  582. m_pZSKKGainMatrix->AverageGainMap(wImage, nRefIndex, bStart);
  583. }
  584. return true;
  585. }
  586. /************************************************************************************
  587. 功能:保存探测器增益校正的结果到磁盘中
  588. 参数:m_nReferenceNum为需要进行探测器增益校正的点数
  589. m_vectorCalMode[0]为配置文件<ProcContent>内容
  590. ************************************************************************************/
  591. bool CZSKKCalibrationCtrl::StoreZSKKGainMap(string strSerial)
  592. {
  593. if (NULL == m_pZSKKGainMatrix)
  594. {
  595. return false;
  596. }
  597. bool bRtn = true;
  598. string strGainFileName;
  599. if (NULL != m_pZSKKGainMatrix)
  600. {
  601. for (int i = 0; i < m_nReferenceNum; i++)
  602. {
  603. //strFile.Format("%s\\%s_%d.cal", m_strRefFilePath, strtemp, i);
  604. strGainFileName = m_strRefFilePath + strSerial + "_" + std::to_string(i) + ".cal";
  605. if (!m_pZSKKGainMatrix->StoreGainMap(strGainFileName.c_str(), i))
  606. {
  607. bRtn = false;
  608. break;
  609. }
  610. }
  611. }
  612. return bRtn;
  613. }
  614. /************************************************************************************
  615. 功能:当bInit为true时,应用于初始化探测器时加载坏点校正文件,
  616. 当磁盘中坏点校正文件不存在时,删除该实例m_pZSKKPixMatrix;
  617. 当bInit为false时,应用于开始探测器增益校正时候,
  618. 先创建一个新的坏点文件(CreateEmptyMap),再加载到内存中(LoadBadPixelMap),
  619. 最后分配校正使用的内存(BeginAutoBadPixels)。
  620. 参数:m_nFullImgWidth为有效区域图像的宽度;
  621. m_nFullImgHeight为有效区域图像的高度;
  622. m_nSaturationValue为图像灰度的饱和值;
  623. ************************************************************************************/
  624. bool CZSKKCalibrationCtrl::LoadZSKKPixelMap(bool bInit, string strSerial)
  625. {
  626. //LogInfo("Load ZSKK Pixel Map");
  627. if (!m_bAutoBadPixel)
  628. {
  629. //LogWarn("Not Auto Bad Pixel ");
  630. return true;
  631. }
  632. if (m_pZSKKPixMatrix)
  633. {
  634. delete m_pZSKKPixMatrix;
  635. m_pZSKKPixMatrix = NULL;
  636. }
  637. m_pZSKKPixMatrix = new CPixMatrix(m_nFullImgWidth, m_nFullImgHeight, 0, 0, m_nSaturationValue);//m_nFullImgWidth, m_nFullImgHeight
  638. if (NULL == m_pZSKKPixMatrix)
  639. {
  640. //LogError("Can not Allocate PixMatrix Memory !");
  641. return false;
  642. }
  643. string strFile;
  644. //为了兼容性考虑,如果加载带序列号的map文件失败,则尝试加载不带序列号的
  645. if (strSerial == "")
  646. {
  647. strFile = m_strRefFilePath + "full.map";
  648. }
  649. else
  650. {
  651. //strFile.Format("%s\\full_%s.map", m_strRefFilePath, strPanelSerial);
  652. strFile = m_strRefFilePath + "full_" + strSerial + ".map";
  653. //FILE* fp;
  654. //fp = fopen(strFile.c_str(), "r");
  655. //if (fp == NULL)
  656. //{
  657. // //strLog.Format("Load %s failed, Error code %u", strFile, dw);
  658. // //LogWarn(strLog);
  659. //}
  660. //if (fp != NULL)
  661. //{
  662. // fclose(fp);
  663. //}
  664. //if (!PathFileExists(strFile.c_str())) //文件不存在
  665. //{
  666. // return false;
  667. //}
  668. }
  669. //LogInfo(strFile);
  670. try
  671. {
  672. if (!bInit)
  673. {
  674. m_pZSKKPixMatrix->BeginAutoBadPixels();
  675. }
  676. else
  677. {
  678. bool result = m_pZSKKPixMatrix->LoadBadPixelMap(strFile.c_str());
  679. if (!result)
  680. {
  681. //LogError("Load Bad Pixel Map Failed");
  682. delete m_pZSKKPixMatrix;
  683. m_pZSKKPixMatrix = NULL;
  684. return false;
  685. }
  686. }
  687. }
  688. catch (...)
  689. {
  690. //LogError("Load Bad Pixel Map Crashed");
  691. delete m_pZSKKPixMatrix;
  692. m_pZSKKPixMatrix = NULL;
  693. }
  694. //LogInfo("Load ZSKK Pixel Map Over");
  695. return true;
  696. }
  697. bool CZSKKCalibrationCtrl::UnLoadZSKKPixMap()
  698. {
  699. //LogInfo("UnLoad Pixel Map");
  700. if (m_pZSKKPixMatrix)
  701. {
  702. delete m_pZSKKPixMatrix;
  703. m_pZSKKPixMatrix = NULL;
  704. }
  705. return true;
  706. }
  707. /************************************************************************************
  708. 功能:应用于图像的坏点校正
  709. 当m_nSaveRawDataMode不为0时,保存校正后的图像数据到rawdata\Clean.raw文件中。
  710. 参数:pImage为输入的原始图像数据,应用图像坏点校正后,输出校正后的图像数据。
  711. ************************************************************************************/
  712. bool CZSKKCalibrationCtrl::ApplyZSKKPixMap(WORD* pImage)
  713. {
  714. if (NULL == m_pZSKKPixMatrix || NULL == pImage)
  715. {
  716. return false;
  717. }
  718. bool bRtn = true;
  719. m_pZSKKPixMatrix->CorrectBadPixels(pImage);
  720. if (m_nSaveRawDataMode != 0)
  721. {
  722. if (!SaveRawImage("Image_Clean.raw", pImage, m_nFullImgWidth, m_nFullImgHeight))
  723. {
  724. //bRtn = false;
  725. }
  726. else
  727. {
  728. //bRtn = true;
  729. }
  730. }
  731. return bRtn;
  732. }
  733. /************************************************************************************
  734. 功能:输入用于探测器坏点校正使用的原始图像数据
  735. 参数:pImage为输入的原始图像数据
  736. ************************************************************************************/
  737. bool CZSKKCalibrationCtrl::AddImageToPixMap(WORD* pImage)
  738. {
  739. //LogInfo("Add Image To BadPixel Map");
  740. if (NULL != m_pZSKKPixMatrix)
  741. {
  742. m_pZSKKPixMatrix->AddImageforBadPixels(pImage);
  743. }
  744. return true;
  745. }
  746. /************************************************************************************
  747. 功能:放弃探测器坏点校正,保持探测器初始化时m_pZSKKPixMatrix的状态
  748. ************************************************************************************/
  749. bool CZSKKCalibrationCtrl::AbortZSKKPixMap(string strSerial)
  750. {
  751. if (!m_bAutoBadPixel)
  752. {
  753. //LogWarn("Not Auto Bad Pixel1 ");
  754. return true;
  755. }
  756. if (NULL != m_pZSKKPixMatrix)
  757. {
  758. m_pZSKKPixMatrix->EndAutoBadPixels(-1);
  759. LoadZSKKPixelMap(true, strSerial); //取消校正后,重新加载原来的校正文件
  760. }
  761. return true;
  762. }
  763. /************************************************************************************
  764. 功能:保存探测器坏点校正的结果到磁盘中
  765. 参数:m_nReferenceNum为需要进行探测器增益校正的点数
  766. m_vectorCalMode[0]为配置文件<ProcContent>内容
  767. ************************************************************************************/
  768. bool CZSKKCalibrationCtrl::StoreZSKKPixMap(string strSerial)
  769. {
  770. if (!m_bAutoBadPixel)
  771. {
  772. //LogWarn("Not Auto Bad Pixel2 ");
  773. return true;
  774. }
  775. if (NULL != m_pZSKKPixMatrix)
  776. {
  777. //CString strFile;
  778. string strFile;
  779. //多板的情况下,如果序列号不为空,则只使用序列号区分full.map,这样调整探测器的workstation时,不用调整full.map的名字
  780. if (strSerial != "")
  781. {
  782. //strFile.Format("%s\\full_%s.map", m_strRefFilePath, strSerial);
  783. strFile = m_strRefFilePath + "\\full_" + strSerial + ".map";
  784. }
  785. else
  786. {
  787. strFile = m_strRefFilePath + "\\full.map";
  788. }
  789. if (!CreateEmptyMap(m_nFullImgHeight, strFile.c_str()))
  790. {
  791. return false;
  792. }
  793. //m_pZSKKPixMatrix->EndAutoBadPixels(1);
  794. //LogInfo("Store Bad Pixels");
  795. m_pZSKKPixMatrix->StoreBadPixels(strFile.c_str(), 1);
  796. }
  797. return true;
  798. }
  799. /************************************************************************************
  800. 功能:初始化时加载探测器坏线校正文件reference\Lin.map
  801. 注意:该函数必须在初始化LoadZSKKPixelMap()后面使用
  802. ************************************************************************************/
  803. bool CZSKKCalibrationCtrl::LoadZSKKLineMap(string strSerial)
  804. {
  805. bool bHaveBadPixelMap = true;
  806. if (NULL == m_pZSKKPixMatrix)
  807. {
  808. bHaveBadPixelMap = false;
  809. m_pZSKKPixMatrix = new CPixMatrix(m_nFullImgWidth, m_nFullImgHeight, 0, 0, m_nSaturationValue);
  810. if (NULL == m_pZSKKPixMatrix)
  811. {
  812. //LogError("Can not Allocate PixMatrix Memory !");
  813. return false;
  814. }
  815. }
  816. //LogInfo("Load ZSKK LineMap");
  817. //CString strFile;
  818. //strFile.Format("%s\\%sDoubleLine.map", m_strRefFilePath, strPanelSerial);
  819. string strFile;
  820. if (strSerial == "")
  821. {
  822. strFile = m_strRefFilePath + "DoubleLine.map";
  823. }
  824. else
  825. {
  826. strFile = m_strRefFilePath + strSerial + "DoubleLine.map";
  827. }
  828. if (m_pZSKKPixMatrix->LoadDLineMap(strFile.c_str()))
  829. {
  830. //LogInfo("Load ZSKK LineMap success");
  831. return true;
  832. }
  833. else
  834. {
  835. //LogInfo("Load ZSKK LineMap failed");
  836. if (!bHaveBadPixelMap)
  837. {
  838. delete m_pZSKKPixMatrix;
  839. m_pZSKKPixMatrix = NULL;
  840. }
  841. return false;
  842. }
  843. }
  844. /************************************************************************************
  845. 功能:应用于图像的坏线校正
  846. 当m_nSaveRawDataMode不为0时,保存校正后的图像数据到DROC\rawdata\Clean-Line.raw文件中。
  847. 参数:pImage为输入的原始图像数据,应用图像坏线校正后,输出校正后的图像数据。
  848. ************************************************************************************/
  849. bool CZSKKCalibrationCtrl::ApplyZSKKLineMap(WORD* pImage)
  850. {
  851. if (NULL == m_pZSKKPixMatrix || NULL == pImage)
  852. {
  853. return false;
  854. }
  855. //LogInfo("Apply ZSKK LineMap");
  856. bool bRtn = true;
  857. m_pZSKKPixMatrix->CorrectDBadLines(pImage);
  858. /*if (m_nSaveRawDataMode != 0)
  859. {
  860. CString strPath = m_strRawImgPath + "\\" + "Clean-Line.raw";
  861. if (!SaveImage(pImage, strPath, m_FullImgInfo.nWidth, m_FullImgInfo.nHeight))
  862. {
  863. bRtn = false;
  864. }
  865. }*/
  866. return bRtn;
  867. }
  868. /************************************************************************************
  869. 功能:保存图像数据pRawImg到磁盘pImgName中
  870. 参数:m_nWidth为有效区域图像的宽度;
  871. m_nHeight为有效区域图像的高度。
  872. ************************************************************************************/
  873. bool CZSKKCalibrationCtrl::SaveRawImage(const char* pImgName, const WORD* pRawImg, int nWidth, int nHeight)
  874. {
  875. if (pRawImg == NULL || pImgName == NULL)
  876. {
  877. return false;
  878. }
  879. string strImagePath = m_strRawImgPath + pImgName;
  880. FILE* fp;
  881. if ((fp = fopen(strImagePath.c_str(), "wb")) == NULL)
  882. {
  883. //DWORD dw = GetLastError();
  884. return false;
  885. }
  886. fwrite(pRawImg, sizeof(WORD), nWidth * nHeight, fp);
  887. if (fp != NULL)
  888. {
  889. fclose(fp);
  890. }
  891. return true;
  892. }
  893. bool CZSKKCalibrationCtrl::ApplyZSKKReference(int nHeight, int nWidth, WORD* pImage)
  894. {
  895. if (m_nSaveRawDataMode != 0)
  896. {
  897. //if (!SaveImage(pImage, "Image_AfterOffset.raw", nWidth, nHeight))
  898. //{
  899. // //LogError("Save AfterOffset Image File Failed");
  900. //}
  901. //else
  902. //{
  903. // //LogInfo("Save AfterOffset Image File Over");
  904. //}
  905. SaveRawImage("Image_AfterOffset.raw", pImage, nWidth, nHeight);
  906. }
  907. bool nRtn = false;
  908. nRtn = ApplyZSKKGainMap(pImage);
  909. if (!nRtn)
  910. {
  911. //LogError("Save AfterGain Image File Failed");
  912. }
  913. else
  914. {
  915. //LogInfo("Save AfterGain Image File Over");
  916. }
  917. nRtn = ApplyZSKKPixMap(pImage);
  918. if (!nRtn)
  919. {
  920. //LogError("Save Clean Image File Failed");
  921. }
  922. else
  923. {
  924. //LogInfo("Save Clean Image File Over");
  925. }
  926. nRtn = GridSuppressed(nHeight, nWidth, pImage);
  927. /*CString strTemp;
  928. strTemp.Format("Grid Suppressed result: %d", nRtn);
  929. LogInfo(strTemp);*/
  930. if (nRtn)
  931. {
  932. //LogInfo("Detected Grid Suppressed");
  933. if (m_nSaveRawDataMode != 0)
  934. {
  935. if (!SaveRawImage("Image_AfterGridSuppressed.raw", pImage, m_nFullImgWidth, m_nFullImgHeight))
  936. {
  937. //bRtn = false;
  938. }
  939. else
  940. {
  941. //bRtn = true;
  942. }
  943. }
  944. }
  945. return true;
  946. }
  947. bool CZSKKCalibrationCtrl::ApplyImageSaturation(WORD* pImage, int nWidth, int nHeight, int nSaturation)
  948. {
  949. //LogInfo("Start ApplyImageSaturation");
  950. if (nSaturation <= 0 || nSaturation >= 65535)
  951. {
  952. //LogInfo("Start ApplyImageSaturation failed");
  953. return false;
  954. }
  955. WORD wSaturation = (WORD)nSaturation;
  956. for (int i = 0; i < nWidth; i++)
  957. {
  958. for (int j = 0; j < nHeight; j++)
  959. {
  960. if (pImage[i * nHeight + j] > wSaturation)
  961. {
  962. pImage[i * nHeight + j] = wSaturation;
  963. }
  964. }
  965. }
  966. //LogInfo("End ApplyImageSaturation");
  967. return true;
  968. }