#include "stdafx.h" #include "ZSKKCalibration.h" using std::string; CZSKKCalibrationCtrl::CZSKKCalibrationCtrl() { m_nGridSuppressed = 0; m_nFullImgWidth = 0; m_nFullImgHeight = 0; m_nHeightOffset = 0; m_nWidthOffset = 0; m_bAutoBadPixel = true; m_nReferenceNum = 3; m_nSaveRawDataMode = 0; m_strRawImgPath = ".\\"; m_strRefFilePath = ".\\"; m_nSaturationValue = 50000; m_pZSKKGainMatrix = NULL; m_pZSKKPixMatrix = NULL; } CZSKKCalibrationCtrl::~CZSKKCalibrationCtrl() { if (m_pZSKKGainMatrix != NULL) { delete m_pZSKKGainMatrix; m_pZSKKGainMatrix = NULL; } if (m_pZSKKPixMatrix != NULL) { delete m_pZSKKPixMatrix; m_pZSKKPixMatrix = NULL; } } //去栅影 bool CZSKKCalibrationCtrl::GridSuppressed(int nHeight, int nWidth, unsigned short* pImage) { //logfile->WriteLog("Process Grid Suppression...", LOG_INFORMATION, LOG_DEBUG, true); if (pImage == NULL) { //logfile->WriteLog("the image buffer is Null.", LOG_ERROR, LOG_DEBUG, true); return false; } bool bResult = false; //CString strLog; //strLog.Format("Current Grid Suppressed: %d", m_nGridSuppressed); //logfile->WriteLog(strLog, LOG_INFORMATION, LOG_DEBUG, true); if (m_nGridSuppressed == 2) { //logfile->WriteLog("Manual: No Grid", LOG_INFORMATION, LOG_DEBUG, true); return false; } if (m_pZSKKPixMatrix) { GridBadLineCorrectFirst(nHeight, nWidth, pImage); } try { int nGridDirection = GridSuppression_US(pImage, nWidth, nHeight, m_nGridSuppressed); //m_nGridDirction = nGridDirection; switch (nGridDirection) { case 1: //logfile->WriteLog("Process Vertical Grid Over", LOG_INFORMATION, LOG_DEBUG, true); bResult = true; //*pnGridDirection = 1; break; case 2: //logfile->WriteLog("Process Horizontal Grid Over", LOG_INFORMATION, LOG_DEBUG, true); bResult = true; //*pnGridDirection = 2; break; case 0: //logfile->WriteLog("No Grid Detected", LOG_INFORMATION, LOG_DEBUG, true); break; case -1: //logfile->WriteLog("The image size is wrong", LOG_WARNING, LOG_DEBUG, true); break; default: //logfile->WriteLog("Unknown Error", LOG_WARNING, LOG_DEBUG, true); break; } if (m_pZSKKPixMatrix) { if ((nGridDirection == 1) || (nGridDirection == 2)) { //LogInfo("Begin to Correct Bad Line"); if (m_pZSKKPixMatrix) { m_pZSKKPixMatrix->LoadandCorrectBadLine(pImage, nGridDirection); //LogInfo("Correct Bad Line Over"); } else { //LogError("Correct Bad Line Failed,No Bad File Map"); } } GridBadLineCorrectSecond(nHeight, nWidth, pImage); } } catch (...) { //LogError("GridSuppression Function is Crash,please Recover Last Image or Not"); } return bResult; } bool CZSKKCalibrationCtrl::GridBadLineCorrectFirst(int nHeight, int nWidth, unsigned short* pImage) { //CString strLog = ""; //LogInfo("Begin to Grid Judgement"); int nGridExist = GridJudgement(pImage, nWidth, nHeight, m_nGridSuppressed); if (nGridExist > 0) //有栅的情况 { //strLog.Format("Grid Judgement Result:%d", nGridExist); //LogInfo(strLog); if (m_pZSKKPixMatrix) { int nDefectType = 0; //只对平行于栅影的坏线处理,2016.07.21 ,zhaoyiru if (1 == nGridExist) //竖直栅影 { for (int i = 0; i < m_pZSKKPixMatrix->m_nLineData; i = i + 4) { if (-1 == m_pZSKKPixMatrix->m_datalen[i]) { break; } if (0 == m_pZSKKPixMatrix->m_datalen[i]) //水平坏线 { nDefectType = 1; int nRtn = m_pZSKKPixMatrix->BadGridLineCorrect1(pImage, m_pZSKKPixMatrix->m_datalen[i], m_pZSKKPixMatrix->m_datalen[i + 1], m_pZSKKPixMatrix->m_datalen[i + 2], m_pZSKKPixMatrix->m_datalen[i + 3], nWidth, nHeight); } if (1 == m_pZSKKPixMatrix->m_datalen[i]) //竖直坏线 { nDefectType += 2; int nRtn = m_pZSKKPixMatrix->BadGridLineCorrect2(pImage, m_pZSKKPixMatrix->m_datalen[i], m_pZSKKPixMatrix->m_datalen[i + 1], m_pZSKKPixMatrix->m_datalen[i + 2], m_pZSKKPixMatrix->m_datalen[i + 3], nWidth, nHeight); } } } else if (2 == nGridExist) //水平栅影 { for (int i = 0; i < m_pZSKKPixMatrix->m_nLineData; i = i + 4) { if (-1 == m_pZSKKPixMatrix->m_datalen[i]) { break; } if (0 == m_pZSKKPixMatrix->m_datalen[i]) //水平坏线 { nDefectType = 1; int nRtn = m_pZSKKPixMatrix->BadGridLineCorrect1(pImage, m_pZSKKPixMatrix->m_datalen[i], m_pZSKKPixMatrix->m_datalen[i + 1], m_pZSKKPixMatrix->m_datalen[i + 2], m_pZSKKPixMatrix->m_datalen[i + 3], nWidth, nHeight); } if (1 == m_pZSKKPixMatrix->m_datalen[i]) //竖直坏线 { nDefectType += 2; int nRtn = m_pZSKKPixMatrix->BadGridLineCorrect2(pImage, m_pZSKKPixMatrix->m_datalen[i], m_pZSKKPixMatrix->m_datalen[i + 1], m_pZSKKPixMatrix->m_datalen[i + 2], m_pZSKKPixMatrix->m_datalen[i + 3], nWidth, nHeight); } } } if (nDefectType == 0) { //LogInfo("No defect lines"); } else if (nDefectType == 1) { //LogInfo("Horizontal defect lines"); } else if (nDefectType % 2 == 0) { //LogInfo("Vertical defect lines"); } else if (nDefectType % 2 == 1) { //LogInfo("Both direction defect lines"); } //if ((1 == nGridExist) || (2 == nGridExist)) //{ // //LogInfo("Switch DoubleBadLines"); // m_pZSKKPixMatrix->SwitchDBadLines(pImage); // if (m_nSaveRawDataMode != 0) // { // if (!SaveImage(pImage, "Image_DoubleBadLinePrep.raw", nHeight, nWidth)) // { // LogError("Save DBadline Prep Image File Failed"); // } // else // { // LogInfo("Save DBadline Prep Image File Over"); // } // } //} return true; } else { //LogWarn("ZSKK PixMatrix is NULL"); return false; } } else { //LogInfo("Grid Judgemet Result:No gird"); return false; } } bool CZSKKCalibrationCtrl::GridBadLineCorrectSecond(int nHeight, int nWidth, unsigned short* pImage) { CString strLog = ""; if (m_pZSKKPixMatrix != NULL) { // 对水平竖直坏线分别处理 int nDefectType = 0; for (int i = 0; i < m_pZSKKPixMatrix->m_nLineData; i = i + 4) { if (-1 == m_pZSKKPixMatrix->m_datalen[i]) { break; } if (1 == m_pZSKKPixMatrix->m_datalen[i]) //竖直坏线 { nDefectType = 1; int nlbadlineRet = 0; nlbadlineRet = m_pZSKKPixMatrix->BadGridLineCorrect4(pImage, m_pZSKKPixMatrix->m_datalen[i], m_pZSKKPixMatrix->m_datalen[i + 1], m_pZSKKPixMatrix->m_datalen[i + 2], m_pZSKKPixMatrix->m_datalen[i + 3], nWidth, nHeight); } if (0 == m_pZSKKPixMatrix->m_datalen[i]) //水平坏线 { nDefectType += 2; int nlbadlineRet = 0; nlbadlineRet = m_pZSKKPixMatrix->BadGridLineCorrect3(pImage, m_pZSKKPixMatrix->m_datalen[i], m_pZSKKPixMatrix->m_datalen[i + 1], m_pZSKKPixMatrix->m_datalen[i + 2], m_pZSKKPixMatrix->m_datalen[i + 3], nWidth, nHeight); } } /*if (nDefectType == 0) { LogInfo("No defect lines"); } else if (nDefectType == 1) { LogInfo("Vertical defect lines"); } else if (nDefectType % 2 == 0) { LogInfo("Horizontal defect lines"); } else if (nDefectType % 2 == 1) { LogInfo("Both direction defect lines"); } if ((nDefectType != 0) && (m_nSaveRawDataMode != 0)) { if (!SaveImage(pImage, "Image_BadLinePost.raw", nHeight, nWidth)) { LogError("Save Grid badline Post Image File Failed"); } else { LogInfo("Save Grid badline Post Image File Over"); } }*/ ApplyZSKKLineMap(pImage); return true; } else { //LogWarn("ZSKK PixMatrix is NULL"); return false; } } //生成新的full map //[IN]: 图像高度 //[IN]:文件路径和名称 bool CZSKKCalibrationCtrl::CreateEmptyMap(int nHeight, const char* pcRefPath) { //Fill the map file char* pMapData = new char[nHeight * 10]; if (NULL == pMapData) { //logfile->WriteLog("Failed to allocate memory", LOG_ERROR, LOG_DEBUG, true); return false; } memset(pMapData, 0, nHeight * 10 * sizeof(char)); int nCharCount = 0; for (int nRow = 0; nRow < nHeight; nRow++) { if (nCharCount >= (nHeight - 2) * 10) { break; } int nLength = sprintf(pMapData + nCharCount, "%d,0:\n", nRow);//need to modify nCharCount += nLength; } //record the buffer size int nBufferSize = nHeight * 10 * sizeof(char); /*CString strLog; strLog.Format("the allocated buffer size is %d", nBufferSize); LogInfo(strLog);*/ //write data to file FILE* pFile = NULL; pFile = fopen(pcRefPath, "wb+"); if (static_cast(fwrite(pMapData, 1, nCharCount, pFile)) != nCharCount) { /*TRACE("Failed to write map"); logfile->WriteLog("Failed to write the defect map th hard disk", LOG_ERROR, LOG_DEBUG, true);*/ return false; } fclose(pFile); if (pMapData != NULL) { delete[] pMapData; pMapData = NULL; } return true; } //int CZSKKCalibrationCtrl::JudgeDarkImage(WORD* pOldData, WORD* pNewData, int nWidth, int nHeight) //{ // logfile->WriteLog("Judging Dark Image", LOG_INFORMATION, LOG_DEBUG, true); // // int m_nDarkImageCheck = 1; // if (!m_nDarkImageCheck) // { // return 0; // } // int nReturn = DarkImageJudge(pOldData, pNewData, nWidth, nHeight, 200, 5); // // if (nReturn >= 0) // { // logfile->WriteLog("Dark Image is valid", LOG_INFORMATION, LOG_DEBUG, true); // return 1; // } // else // { // logfile->WriteLog("Dark Image is Invalid", LOG_ERROR, LOG_DEBUG, true); // return -1; // } //} //int CZSKKCalibrationCtrl::JudgeWhiteImage(WORD* pwData, int nWidth, int nHeight, int nWidthOffset, int nHeightOffset, unsigned short nCurrentTargetDV) //{ // int m_nWhiteImageCheck = 1; // if (!m_nWhiteImageCheck) // { // return -5; // } // else // { // int nReturn = FlatImageCheck(pwData, nWidth, nHeight, nWidthOffset, nHeightOffset, nCurrentTargetDV, 0.1f, 0.2f, 0.1f); // CString strLog; // strLog.Format("The returned value of FlatImageCheck function is %d", nReturn); // logfile->WriteLog(strLog, LOG_INFORMATION, LOG_DEBUG, true); // if (nReturn >= 0)//correct // { // logfile->WriteLog("The flat image is able to use!", LOG_INFORMATION, LOG_DEBUG, true); // return 1; // } // else if (nReturn == -1)// the average dv are more or less than 10 percent of the predefined value // { // logfile->WriteLog("The average pixel value is out of the range of the target value", LOG_WARNING, LOG_DEBUG, true); // //::PostMessage(this->m_hWnd,MSG_PANEL_STATUS,PNL_READY,NULL); // return -1; // } // else if (nReturn == -2)// not flat // { // logfile->WriteLog("The image is not flat", LOG_WARNING, LOG_DEBUG, true); // //::PostMessage(this->m_hWnd,MSG_PANEL_STATUS,PNL_READY,NULL); // return -2; // // } // else//wrong // { // logfile->WriteLog("The flat image is invalid!", LOG_WARNING, LOG_DEBUG, true); // return -3; // } // } //} //method to reset gain calibration process object; bool CZSKKCalibrationCtrl::CreateGainMatrix(CGainMatrix* pGainMatrix, int nWidth, int nHeight, int nWidthOffset, int nHeightOffset, int nRefrenceNum, WORD wMaxPv) { //destroy object before; if (NULL != pGainMatrix) { delete pGainMatrix; pGainMatrix = NULL; } //create new object; pGainMatrix = new CGainMatrix(nWidth, nHeight, nWidthOffset, nHeightOffset, nRefrenceNum, wMaxPv); if (pGainMatrix == NULL) { return false; } bool m_bGainMAPReady = true; if (NULL != pGainMatrix) { for (size_t nIndex = 0; nIndex < nRefrenceNum; nIndex++) { //CString strFileName; //strFileName.Format("%s\\TETD_Gain_%d_%d.cal", m_strReferencePath, m_panelXmlStruct.nPanelGainMode, nIndex); string strFileName = "TETD_Gain_.cal"; if (!pGainMatrix->LoadGainMap(strFileName.c_str())) { //logfile->WriteLog("Fail to load gain map!", LOG_WARNING, LOG_DEBUG, true); m_bGainMAPReady = false; break; } } if (!m_bGainMAPReady) { delete pGainMatrix; pGainMatrix = NULL; } } else { //logfile->WriteLog("Failed to allocate memory", LOG_ERROR, LOG_DEBUG, true); return false; } return m_bGainMAPReady; } bool CZSKKCalibrationCtrl::BeginGainCalibration(CGainMatrix* pGainMatrix, int nWidth, int nHeight, int nWidthOffset, int nHeightOffset, int nRefrenceNum, WORD wMaxPv) { if (pGainMatrix) { delete pGainMatrix; } pGainMatrix = new CGainMatrix(nWidth, nHeight, nWidthOffset, nHeightOffset, nRefrenceNum, wMaxPv); if (pGainMatrix == NULL) { return false; } for (int i = 0; i < nRefrenceNum; i++) { if (!pGainMatrix->LoadGainMap()) { return false; } } return true; } /************************************************************************************ 预处理模块调用示例: 初始化探测器InitPanel LoadZSKKGainMap() LoadZSKKPixelMap() LoadZSKKLineMap() 退出探测器ExitPanel UnLoadZSKKGainMap() UnLoadZSKKPixMap() 图像校正OnTransImgEnd ApplyZSKKGainMap(pImage) ApplyZSKKPixMap(pImage) ApplyZSKKLineMap(pImage) 开始探测器校正StartCalibration LoadZSKKGainMap(false) LoadZSKKPixelMap(false) 中止探测器校正 LoadZSKKGainMap() AbortZSKKPixMap() 接受当前探测器校正图像 AverageZSKKGainMap(pImage) AddImageToPixMap(pImage) 完成探测器校正 StoreZSKKGainMap() StoreZSKKPixMap() ************************************************************************************/ /************************************************************************************ 功能:当bInit为true时,应用于初始化探测器时加载增益校正文件, 磁盘中增益校正文件不存在时,删除该实例m_pZSKKGainMatrix; 当bInit为false时,应用于开始探测器增益校正时候, 重新分配增益校正内存,忽略磁盘中的校正文件。 注意:两个LoadGainMap的形参不同,作用不同。 参数:m_nWidth为有效区域图像的宽度; m_nHeight为有效区域图像的高度; m_nSaturationValue为图像灰度的饱和值 m_nReferenceNum为需要进行校正的点数 m_vectorCalMode[0]为配置文件内容 ************************************************************************************/ bool CZSKKCalibrationCtrl::LoadZSKKGainMap(bool bInit, string strSerial) { //LogInfo("Load ZSKK Gain Cal File"); //destroy object before; if (m_pZSKKGainMatrix) { delete m_pZSKKGainMatrix; m_pZSKKGainMatrix = NULL; } /*CString str; str.Format("FullImgWidth [%d],FullImgHeight [%d],SaturationValue [%d]", m_nFullImgWidth, m_nFullImgHeight, m_nSaturationValue); LogInfo(str);*/ m_pZSKKGainMatrix = new CGainMatrix(m_nFullImgWidth, m_nFullImgHeight, 0, 0, m_nReferenceNum, m_nSaturationValue);//m_nReferenceNum if (NULL == m_pZSKKGainMatrix) { //LogError("ZSKKGainMatrix Allocate Failed"); return false; } bool bRtn = true; //CString strFile; //CString strtemp = strGain + m_vectorCalMode[0]; //LogInfo(strtemp); string strGainFileName; if (bInit) { for (int i = 0; i < m_nReferenceNum; i++) { //strFile.Format("%s\\%s_%d.cal", m_strRefFilePath, strtemp, i); strGainFileName = m_strRefFilePath + strSerial + "_" + std::to_string(i) + ".cal"; if (!m_pZSKKGainMatrix->LoadGainMap(strGainFileName.c_str())) { //LogError("Fail to Load gain Map"); bRtn = false; break; } /*else { LogInfo(strFile); }*/ } } else { for (int i = 0; i < m_nReferenceNum; i++) { if (!m_pZSKKGainMatrix->LoadGainMap()) { bRtn = false; break; } } } if (!bRtn) { delete m_pZSKKGainMatrix; m_pZSKKGainMatrix = NULL; } return bRtn; } bool CZSKKCalibrationCtrl::UnLoadZSKKGainMap() { if (m_pZSKKGainMatrix) { delete m_pZSKKGainMatrix; m_pZSKKGainMatrix = NULL; } return true; } /************************************************************************************ 功能:应用于图像的增益校正 当m_nSaveRawDataMode不为0时,保存校正后的图像数据到rawdata\AfterGain.raw文件中。 参数:pImage为输入的原始图像数据,应用图像增益校正后,输出校正后的图像数据。 ************************************************************************************/ bool CZSKKCalibrationCtrl::ApplyZSKKGainMap(WORD* pImage) { if (NULL == m_pZSKKGainMatrix || NULL == pImage) { return false; } bool bRtn = true; //LogInfo("Apply Gain Correction"); m_pZSKKGainMatrix->ApplyGainMap(pImage); if (m_nSaveRawDataMode != 0) { if (!SaveRawImage("Image_AfterGain.raw", pImage, m_nFullImgWidth, m_nFullImgHeight)) { //bRtn = false; } else { //bRtn = true; } } //LogInfo("Apply Gain Correction Over"); return true; } /************************************************************************************ 功能:输入用于探测器增益校正使用的原始图像数据 参数:pImage为输入的原始图像数据 ************************************************************************************/ bool CZSKKCalibrationCtrl::AverageZSKKGainMap(WORD* wImage, int nRefIndex, bool bStart) { //("Average Gain Map"); if (NULL != m_pZSKKGainMatrix) { m_pZSKKGainMatrix->AverageGainMap(wImage, nRefIndex, bStart); } return true; } /************************************************************************************ 功能:保存探测器增益校正的结果到磁盘中 参数:m_nReferenceNum为需要进行探测器增益校正的点数 m_vectorCalMode[0]为配置文件内容 ************************************************************************************/ bool CZSKKCalibrationCtrl::StoreZSKKGainMap(string strSerial) { if (NULL == m_pZSKKGainMatrix) { return false; } bool bRtn = true; string strGainFileName; if (NULL != m_pZSKKGainMatrix) { for (int i = 0; i < m_nReferenceNum; i++) { //strFile.Format("%s\\%s_%d.cal", m_strRefFilePath, strtemp, i); strGainFileName = m_strRefFilePath + strSerial + "_" + std::to_string(i) + ".cal"; if (!m_pZSKKGainMatrix->StoreGainMap(strGainFileName.c_str(), i)) { bRtn = false; break; } } } return bRtn; } /************************************************************************************ 功能:当bInit为true时,应用于初始化探测器时加载坏点校正文件, 当磁盘中坏点校正文件不存在时,删除该实例m_pZSKKPixMatrix; 当bInit为false时,应用于开始探测器增益校正时候, 先创建一个新的坏点文件(CreateEmptyMap),再加载到内存中(LoadBadPixelMap), 最后分配校正使用的内存(BeginAutoBadPixels)。 参数:m_nFullImgWidth为有效区域图像的宽度; m_nFullImgHeight为有效区域图像的高度; m_nSaturationValue为图像灰度的饱和值; ************************************************************************************/ bool CZSKKCalibrationCtrl::LoadZSKKPixelMap(bool bInit, string strSerial) { //LogInfo("Load ZSKK Pixel Map"); if (!m_bAutoBadPixel) { //LogWarn("Not Auto Bad Pixel "); return true; } if (m_pZSKKPixMatrix) { delete m_pZSKKPixMatrix; m_pZSKKPixMatrix = NULL; } m_pZSKKPixMatrix = new CPixMatrix(m_nFullImgWidth, m_nFullImgHeight, 0, 0, m_nSaturationValue);//m_nFullImgWidth, m_nFullImgHeight if (NULL == m_pZSKKPixMatrix) { //LogError("Can not Allocate PixMatrix Memory !"); return false; } string strFile; //为了兼容性考虑,如果加载带序列号的map文件失败,则尝试加载不带序列号的 if (strSerial == "") { strFile = m_strRefFilePath + "full.map"; } else { //strFile.Format("%s\\full_%s.map", m_strRefFilePath, strPanelSerial); strFile = m_strRefFilePath + "full_" + strSerial + ".map"; //FILE* fp; //fp = fopen(strFile.c_str(), "r"); //if (fp == NULL) //{ // //strLog.Format("Load %s failed, Error code %u", strFile, dw); // //LogWarn(strLog); //} //if (fp != NULL) //{ // fclose(fp); //} //if (!PathFileExists(strFile.c_str())) //文件不存在 //{ // return false; //} } //LogInfo(strFile); try { if (!bInit) { m_pZSKKPixMatrix->BeginAutoBadPixels(); } else { bool result = m_pZSKKPixMatrix->LoadBadPixelMap(strFile.c_str()); if (!result) { //LogError("Load Bad Pixel Map Failed"); delete m_pZSKKPixMatrix; m_pZSKKPixMatrix = NULL; return false; } } } catch (...) { //LogError("Load Bad Pixel Map Crashed"); delete m_pZSKKPixMatrix; m_pZSKKPixMatrix = NULL; } //LogInfo("Load ZSKK Pixel Map Over"); return true; } bool CZSKKCalibrationCtrl::UnLoadZSKKPixMap() { //LogInfo("UnLoad Pixel Map"); if (m_pZSKKPixMatrix) { delete m_pZSKKPixMatrix; m_pZSKKPixMatrix = NULL; } return true; } /************************************************************************************ 功能:应用于图像的坏点校正 当m_nSaveRawDataMode不为0时,保存校正后的图像数据到rawdata\Clean.raw文件中。 参数:pImage为输入的原始图像数据,应用图像坏点校正后,输出校正后的图像数据。 ************************************************************************************/ bool CZSKKCalibrationCtrl::ApplyZSKKPixMap(WORD* pImage) { if (NULL == m_pZSKKPixMatrix || NULL == pImage) { return false; } bool bRtn = true; m_pZSKKPixMatrix->CorrectBadPixels(pImage); if (m_nSaveRawDataMode != 0) { if (!SaveRawImage("Image_Clean.raw", pImage, m_nFullImgWidth, m_nFullImgHeight)) { //bRtn = false; } else { //bRtn = true; } } return bRtn; } /************************************************************************************ 功能:输入用于探测器坏点校正使用的原始图像数据 参数:pImage为输入的原始图像数据 ************************************************************************************/ bool CZSKKCalibrationCtrl::AddImageToPixMap(WORD* pImage) { //LogInfo("Add Image To BadPixel Map"); if (NULL != m_pZSKKPixMatrix) { m_pZSKKPixMatrix->AddImageforBadPixels(pImage); } return true; } /************************************************************************************ 功能:放弃探测器坏点校正,保持探测器初始化时m_pZSKKPixMatrix的状态 ************************************************************************************/ bool CZSKKCalibrationCtrl::AbortZSKKPixMap(string strSerial) { if (!m_bAutoBadPixel) { //LogWarn("Not Auto Bad Pixel1 "); return true; } if (NULL != m_pZSKKPixMatrix) { m_pZSKKPixMatrix->EndAutoBadPixels(-1); LoadZSKKPixelMap(true, strSerial); //取消校正后,重新加载原来的校正文件 } return true; } /************************************************************************************ 功能:保存探测器坏点校正的结果到磁盘中 参数:m_nReferenceNum为需要进行探测器增益校正的点数 m_vectorCalMode[0]为配置文件内容 ************************************************************************************/ bool CZSKKCalibrationCtrl::StoreZSKKPixMap(string strSerial) { if (!m_bAutoBadPixel) { //LogWarn("Not Auto Bad Pixel2 "); return true; } if (NULL != m_pZSKKPixMatrix) { //CString strFile; string strFile; //多板的情况下,如果序列号不为空,则只使用序列号区分full.map,这样调整探测器的workstation时,不用调整full.map的名字 if (strSerial != "") { //strFile.Format("%s\\full_%s.map", m_strRefFilePath, strSerial); strFile = m_strRefFilePath + "\\full_" + strSerial + ".map"; } else { strFile = m_strRefFilePath + "\\full.map"; } if (!CreateEmptyMap(m_nFullImgHeight, strFile.c_str())) { return false; } //m_pZSKKPixMatrix->EndAutoBadPixels(1); //LogInfo("Store Bad Pixels"); m_pZSKKPixMatrix->StoreBadPixels(strFile.c_str(), 1); } return true; } /************************************************************************************ 功能:初始化时加载探测器坏线校正文件reference\Lin.map 注意:该函数必须在初始化LoadZSKKPixelMap()后面使用 ************************************************************************************/ bool CZSKKCalibrationCtrl::LoadZSKKLineMap(string strSerial) { bool bHaveBadPixelMap = true; if (NULL == m_pZSKKPixMatrix) { bHaveBadPixelMap = false; m_pZSKKPixMatrix = new CPixMatrix(m_nFullImgWidth, m_nFullImgHeight, 0, 0, m_nSaturationValue); if (NULL == m_pZSKKPixMatrix) { //LogError("Can not Allocate PixMatrix Memory !"); return false; } } //LogInfo("Load ZSKK LineMap"); //CString strFile; //strFile.Format("%s\\%sDoubleLine.map", m_strRefFilePath, strPanelSerial); string strFile; if (strSerial == "") { strFile = m_strRefFilePath + "DoubleLine.map"; } else { strFile = m_strRefFilePath + strSerial + "DoubleLine.map"; } if (m_pZSKKPixMatrix->LoadDLineMap(strFile.c_str())) { //LogInfo("Load ZSKK LineMap success"); return true; } else { //LogInfo("Load ZSKK LineMap failed"); if (!bHaveBadPixelMap) { delete m_pZSKKPixMatrix; m_pZSKKPixMatrix = NULL; } return false; } } /************************************************************************************ 功能:应用于图像的坏线校正 当m_nSaveRawDataMode不为0时,保存校正后的图像数据到DROC\rawdata\Clean-Line.raw文件中。 参数:pImage为输入的原始图像数据,应用图像坏线校正后,输出校正后的图像数据。 ************************************************************************************/ bool CZSKKCalibrationCtrl::ApplyZSKKLineMap(WORD* pImage) { if (NULL == m_pZSKKPixMatrix || NULL == pImage) { return false; } //LogInfo("Apply ZSKK LineMap"); bool bRtn = true; m_pZSKKPixMatrix->CorrectDBadLines(pImage); /*if (m_nSaveRawDataMode != 0) { CString strPath = m_strRawImgPath + "\\" + "Clean-Line.raw"; if (!SaveImage(pImage, strPath, m_FullImgInfo.nWidth, m_FullImgInfo.nHeight)) { bRtn = false; } }*/ return bRtn; } /************************************************************************************ 功能:保存图像数据pRawImg到磁盘pImgName中 参数:m_nWidth为有效区域图像的宽度; m_nHeight为有效区域图像的高度。 ************************************************************************************/ bool CZSKKCalibrationCtrl::SaveRawImage(const char* pImgName, const WORD* pRawImg, int nWidth, int nHeight) { //Info("Begin to Save {$} Image, width: {$}, height: {$}", pImgName, nWidth, nHeight); if (pRawImg == NULL || pImgName == NULL) { return false; } string strImagePath = m_strRawImgPath + pImgName; FILE* fp; if ((fp = fopen(strImagePath.c_str(), "wb+")) == NULL) { //DWORD dw = GetLastError(); //Error("fopen {$} failed, {$}", strImagePath.c_str(), dw); return false; } fwrite(pRawImg, sizeof(WORD), nWidth * nHeight, fp); if (fp != NULL) { fclose(fp); } //Info("End to Save Raw Image"); return true; } bool CZSKKCalibrationCtrl::ApplyZSKKReference(int nHeight, int nWidth, WORD* pImage) { if (m_nSaveRawDataMode != 0) { //if (!SaveImage(pImage, "Image_AfterOffset.raw", nWidth, nHeight)) //{ // //LogError("Save AfterOffset Image File Failed"); //} //else //{ // //LogInfo("Save AfterOffset Image File Over"); //} SaveRawImage("Image_AfterOffset.raw", pImage, nWidth, nHeight); } bool nRtn = false; nRtn = ApplyZSKKGainMap(pImage); if (!nRtn) { //LogError("Save AfterGain Image File Failed"); } else { //LogInfo("Save AfterGain Image File Over"); } nRtn = ApplyZSKKPixMap(pImage); if (!nRtn) { //LogError("Save Clean Image File Failed"); } else { //LogInfo("Save Clean Image File Over"); } nRtn = GridSuppressed(nHeight, nWidth, pImage); /*CString strTemp; strTemp.Format("Grid Suppressed result: %d", nRtn); LogInfo(strTemp);*/ if (nRtn) { //LogInfo("Detected Grid Suppressed"); if (m_nSaveRawDataMode != 0) { if (!SaveRawImage("Image_AfterGridSuppressed.raw", pImage, m_nFullImgWidth, m_nFullImgHeight)) { //bRtn = false; } else { //bRtn = true; } } } return true; } bool CZSKKCalibrationCtrl::ApplyImageSaturation(WORD* pImage, int nWidth, int nHeight, int nSaturation) { //LogInfo("Start ApplyImageSaturation"); if (nSaturation <= 0 || nSaturation >= 65535) { //LogInfo("Start ApplyImageSaturation failed"); return false; } WORD wSaturation = (WORD)nSaturation; for (int i = 0; i < nWidth; i++) { for (int j = 0; j < nHeight; j++) { if (pImage[i * nHeight + j] > wSaturation) { pImage[i * nHeight + j] = wSaturation; } } } //LogInfo("End ApplyImageSaturation"); return true; }