#include "stdafx.h" #include "Detector_TeledyneDalsa.h" #include "CCOS.Dev.FPD.TeledyneDalsa.h" extern Log4CPP::Logger* gLogger; Detector_TeledyneDalsa* g_pTeledyneDalsaInstance = nullptr; constexpr auto FRAME_NUMBER = 10; constexpr auto RAD_HEADER_SIZE = 65536; //SDK Rad模式图像头 inline int GetReturnCode(int nCode) { return nCode / 100000; } Detector_TeledyneDalsa* g_pDetector = nullptr; #define LOAD_PROC_ADDRESS(handle,func) \ if ((func = (CB_##func)GetProcAddress(handle, #func)) == NULL) { printf("Error occurs while loading entry point!!! \n'%s'\n", #func); }\ void CALLBACK G_Teledyne_OnEvent(int nIndex, void* context) { g_pTeledyneDalsaInstance->CallbackProcess(nIndex, context); } void CALLBACK Dark_Teledyne_OnEvent(int nIndex, void* context) { g_pTeledyneDalsaInstance->DarkCallbackProcess(nIndex, context); } void CALLBACK Gain_Teledyne_OnEvent(int nIndex, void* context) { g_pTeledyneDalsaInstance->GainCallbackProcess(nIndex, context); } Detector_TeledyneDalsa::Detector_TeledyneDalsa() { g_pTeledyneDalsaInstance = this; m_pDPC2PanelID = new map(); m_pPanelID2DPC = new map(); m_nPanelCount = 0; m_hTeledyneDalsaModule = nullptr; m_nCurrentPanelID = 0; m_nLastLogicMode = -1; m_nCurrentLogicMode = -1; m_pImageBuffer = nullptr; m_pRawImgBuffer = nullptr; m_pFullImgBuffer = nullptr; m_bSaveRaw = false; m_strWorkPath = ""; m_eCaliType = CCOS_CALIBRATION_TYPE_NONE; m_eStatus = eDetStatus::DetStatus_NotIni; m_nImageHeight = 0; m_nImageWidth = 0; m_nCropLeft = 0; m_nCropRight = 0; m_nCropTop = 0; m_nCropBottom = 0; m_nRawImgHeight = 0; m_nRawImgWidth = 0; m_nImgIndex = 0; m_nAcqReadyTimeout = 20; m_nGainReadyTimeout = 20; m_nOftRefreshTimer = 20; m_bIsRadMode = false; m_bSendImgToUpper = true; m_nDropImgNum = 0; m_nDropImgCount = 0; m_nExamMode = APP_STATUS_MAX; m_bAbortRefreshOft = false; m_hFPDScanThread = nullptr; m_hRefreshOftThread = nullptr; //m_bFramePrep = false; m_fFrameRate = 1; //缺省值,1帧每秒 m_nDelayTime = 0; m_bStartGrab = false; //m_nXrayOnNum = 0; m_nValidImgNum = 0; m_nExposureCount = -1; m_nExiThreshold = 200;//新增配置 m_bFirstImage = true; InitializeCriticalSection(&m_cs); m_hStopScanEvent = CreateEvent(NULL, FALSE, FALSE, NULL); m_hAcqEvent = CreateEvent(NULL, FALSE, FALSE, NULL); m_hGainEvent = CreateEvent(NULL, FALSE, FALSE, NULL); m_hDarkEvent = CreateEvent(NULL, FALSE, FALSE, NULL); m_hProcessImgEvent = CreateEvent(NULL, FALSE, FALSE, NULL); m_hArrayEvent[0] = m_hStopScanEvent; m_hArrayEvent[1] = m_hAcqEvent; m_hArrayEvent[2] = m_hGainEvent; m_hArrayEvent[3] = m_hDarkEvent; m_hArrayEvent[4] = m_hProcessImgEvent; m_hAcqReadyEvent = CreateEvent(NULL, FALSE, FALSE, NULL); m_hGainReadyEvent = CreateEvent(NULL, FALSE, FALSE, NULL); m_hOftEndEvent = CreateEvent(NULL, FALSE, FALSE, NULL); m_hImageEvent = CreateEvent(NULL, FALSE, FALSE, NULL); } Detector_TeledyneDalsa::~Detector_TeledyneDalsa() { if (m_hStopScanEvent) { CloseHandle(m_hStopScanEvent); m_hStopScanEvent = nullptr; } if (m_hAcqEvent) { CloseHandle(m_hAcqEvent); m_hAcqEvent = nullptr; } if (m_hAcqReadyEvent) { CloseHandle(m_hAcqReadyEvent); m_hAcqReadyEvent = nullptr; } if (m_hGainEvent) { CloseHandle(m_hGainEvent); m_hGainEvent = nullptr; } if (m_hGainReadyEvent) { CloseHandle(m_hGainReadyEvent); m_hGainReadyEvent = nullptr; } if (m_hDarkEvent) { CloseHandle(m_hDarkEvent); m_hDarkEvent = nullptr; } if (m_hProcessImgEvent) { CloseHandle(m_hProcessImgEvent); m_hProcessImgEvent = nullptr; } if (m_hOftEndEvent) { CloseHandle(m_hOftEndEvent); m_hOftEndEvent = nullptr; } if (m_hImageEvent) { CloseHandle(m_hImageEvent); m_hImageEvent = nullptr; } if (m_pImageBuffer) { delete[]m_pImageBuffer; m_pImageBuffer = nullptr; } if (m_pRawImgBuffer) { delete[]m_pRawImgBuffer; m_pRawImgBuffer = nullptr; } if (m_pFullImgBuffer != nullptr) { delete[]m_pFullImgBuffer; m_pFullImgBuffer = nullptr; } } bool Detector_TeledyneDalsa::DriverEntry(void* pDrvDPC, ResDataObject& Configuration) { printf("--Func-- DriverEntry %p\n", pDrvDPC); Info("--Func-- DriverEntry {$}", pDrvDPC); map::iterator DPCsIter = m_pDPC2PanelID->find(pDrvDPC); if (DPCsIter != m_pDPC2PanelID->end()) { //printf("This DPC already exist\n"); Error("This DPC already exist"); return false; } m_pDPC2PanelID->insert(pair(pDrvDPC, m_nPanelCount)); m_pPanelID2DPC->insert(pair(m_nPanelCount, pDrvDPC)); m_nPanelCount++; m_ModeConfig = Configuration; //记录配置 --目前只有一个平板,多板时应该分别存储 return true; } bool Detector_TeledyneDalsa::Connect(void* pDrvDPC, const char* szWorkPath) { printf("Connect detector begin \r\n"); Info("Connect detector begin \n"); if ((*m_pDPC2PanelID)[pDrvDPC] != m_nCurrentPanelID) { Debug("Not current DPC, return true"); //printf("Not current DPC, return true \n"); return true; } m_strWorkPath = szWorkPath; try { int nModeCount = (int)m_ModeConfig["ModeTable"].GetKeyCount("DetectorMode"); for (int i = 0; i < nModeCount; i++) { Info("mode count:{$}",i); int nAppModeID = (int)m_ModeConfig["ModeTable"][i]["LogicMode"];//Connect int nModeID = (int)m_ModeConfig["ModeTable"][i]["OperationMode"]; int nGainID = (int)m_ModeConfig["ModeTable"][i]["GainValue"]; string strFrameRate = (string)m_ModeConfig["ModeTable"][i]["Frequency"]; float fFrameRate = stof(strFrameRate.c_str()); int nExpTime = (int)m_ModeConfig["ModeTable"][i]["ExpTime"]; int nTrigType = (int)m_ModeConfig["ModeTable"][i]["ExamType"]; m_nDelayTime = (int)m_ModeConfig["ModeTable"][i]["DelayTime"]; Info("config m_nDelayTime:{$}", m_nDelayTime); } m_nExiThreshold = (int)m_ModeConfig["ExiThreshold"]; Info("image exi threshold:{$}", m_nExiThreshold); m_nAcqReadyTimeout = (int)m_ModeConfig["WorkReadyTimeout"]; m_nGainReadyTimeout = (int)m_ModeConfig["GainReadyTimeout"]; //在Ccos_DROC中进入检查界面后没有停止刷新offset的按钮故此处配置为0,表示不刷新offset m_nOftRefreshTimer = (int)m_ModeConfig["OffsetRefreshTimeout"]; m_strSerialNum = (std::string)m_ModeConfig["SerialNum"]; Info("Acq timeout({$}), Gain timeout({$}), OftRefresh timeout({$}), Serial Num({$})", m_nAcqReadyTimeout, m_nGainReadyTimeout, m_nOftRefreshTimer, m_strSerialNum); } catch (ResDataObjectExption &e) { Error("Get config error: {$}", e.what()); return false; } if (!OpenDetector()) { Error("Open detector failed, Connect failed \n"); return false; } if (m_nOftRefreshTimer != 0) //0表示不刷新 { RefreshAllOffset(); m_bAbortRefreshOft = false; DWORD dwThreadId; if (nullptr == m_hRefreshOftThread) { m_hRefreshOftThread = CreateThread(NULL, 0, RefreshOffsetThread, this, 0, &dwThreadId); } } if (nullptr == m_hFPDScanThread) { unsigned uThreadId; _beginthreadex(NULL, 0, onFPDScanThread, this, 0, &uThreadId); m_hFPDScanThread = OpenThread(THREAD_ALL_ACCESS, TRUE, uThreadId); } Info("Connect over"); printf("Connect over \n"); return true; } void Detector_TeledyneDalsa::DisConnect() { printf("DisConnect with detector \n"); if (eDetStatus::DetStatus_XrayCalibration == GetTeledyneDalsaDPCStatus() || eDetStatus::DetStatus_Offset == GetTeledyneDalsaDPCStatus()) { Info("DisConnect Calling StopCalibration"); if (!m_cGigeDevice.Stop()) { Error("StopAcquisition failed, reason:({$})", m_cGigeDevice.GetLastStatus()); } m_bAbortRefreshOft = true; //退出时停止offset线程 } if (m_pImageBuffer) { delete[]m_pImageBuffer; m_pImageBuffer = nullptr; } if (m_pRawImgBuffer) { delete[]m_pRawImgBuffer; m_pRawImgBuffer = nullptr; } Info("Calling Disconnect"); m_cGigeDevice.Disconnect(); Info("Disconnect Detector Over"); } void Detector_TeledyneDalsa::EnterExamMode(int nExamMode) { switch (nExamMode) { case APP_STATUS_WORK_BEGIN: Info("Enter into Exam Windows"); m_nExamMode = APP_STATUS_WORK_BEGIN; break; case APP_STATUS_WORK_END: Info("Quit Exam Windows"); m_nExamMode = APP_STATUS_WORK_END; break; case APP_STATUS_DETSHARE_BEGIN: Info("Enter into Detector Share Windows"); m_nExamMode = APP_STATUS_DETSHARE_BEGIN; break; case APP_STATUS_DETSHAR_END: m_nExamMode = APP_STATUS_IDLE; Info("Quit Detector Share Windows"); m_nExamMode = APP_STATUS_DETSHAR_END; break; case APP_STATUS_CAL_BEGIN: Info("Enter into Calibration Windows"); m_nExamMode = APP_STATUS_CAL_BEGIN; break; case APP_STATUS_CAL_END: Info("Quit Calibration Windows"); m_nExamMode = APP_STATUS_CAL_END; break; case APP_STATUS_WORK_IN_SENSITIVITY: Info("Enter into sensitivity test interface"); m_nExamMode = APP_STATUS_WORK_IN_SENSITIVITY; break; default: break; } if (APP_STATUS_WORK_END == m_nExamMode) { if (eDetStatus::DetStatus_Acquire == GetTeledyneDalsaDPCStatus()) { StopAcquisitionInside(); } } } bool Detector_TeledyneDalsa::SetAcqMode(int nMode) { printf("SetAcqMode nMode:%d \n", nMode); Info("SetAcqMode nMode:{$}",nMode); if (m_nCurrentLogicMode == nMode) { Info("Same mode, return"); return true; } m_nCurrentLogicMode = -1; //恢复初值 if (eDetStatus::DetStatus_Acquire == GetTeledyneDalsaDPCStatus()) { StopAcquisitionInside(); } try { int nModeCount = (int)m_ModeConfig["ModeTable"].GetKeyCount("DetectorMode"); for (int i = 0; i < nModeCount; i++) { int nAppModeID = (int)m_ModeConfig["ModeTable"][i]["LogicMode"];//SetAcqMode if (nAppModeID == nMode) { printf("find LogicMode == nMode \n"); Info("find LogicMode == nMode"); m_nImageWidth = (int)m_ModeConfig["ModeTable"][i]["ImageWidth"]; m_nImageHeight = (int)m_ModeConfig["ModeTable"][i]["ImageHeight"]; m_nCropLeft = (int)m_ModeConfig["ModeTable"][i]["DeadLineLeft"]; m_nCropRight = (int)m_ModeConfig["ModeTable"][i]["DeadLineRight"]; m_nCropTop = (int)m_ModeConfig["ModeTable"][i]["DeadLineTop"]; m_nCropBottom = (int)m_ModeConfig["ModeTable"][i]["DeadLineBottom"]; m_nRawImgHeight = (int)m_ModeConfig["ModeTable"][i]["RawImgWidth"]; m_nRawImgWidth = (int)m_ModeConfig["ModeTable"][i]["RawImgHeight"]; //m_nImgBits = (int)m_ModeConfig["ModeTable"][i]["PhySizeInfoBit"]; m_strCurrentExamType = (std::string)m_ModeConfig["ModeTable"][i]["ExamType"]; m_nDropImgCount = (int)m_ModeConfig["ModeTable"][i]["DropImgCount"]; m_bSaveRaw = (int)m_ModeConfig["ModeTable"][i]["IsSaveRaw"]; Info("ImgX: {$}, ImgY: {$}, Crop left: {$}, top: {$}, right: {$}, bottom: {$}", m_nImageWidth, m_nImageHeight, m_nCropLeft, m_nCropTop, m_nCropRight, m_nCropBottom); Info("RawImgX: {$}, RawImgY: {$}, ExamType: {$}, DropImgCount: {$}, SaveRaw: {$}", m_nRawImgWidth, m_nRawImgHeight, m_strCurrentExamType, m_nDropImgCount, m_bSaveRaw); if (nullptr != m_pRawImgBuffer) { delete[]m_pRawImgBuffer; m_pRawImgBuffer = nullptr; } m_pRawImgBuffer = new WORD[(size_t)m_nRawImgWidth * (size_t)m_nRawImgHeight]; if (nullptr != m_pFullImgBuffer) { delete[]m_pFullImgBuffer; m_pFullImgBuffer = nullptr; } m_pFullImgBuffer = new WORD[(size_t)m_nRawImgWidth * (size_t)m_nImageHeight]; m_nCurrentLogicMode = nMode; //临时写死 /*if (1 == nMode) { m_bIsRadMode = true; } else { m_bIsRadMode = false; }*/ break; } } } catch (ResDataObjectExption& e) { Error("Read configuration failed, Error code: {$}", e.what()); return false; } //m_nXrayOnNum = 0; //选择模式,恢复初值 m_nValidImgNum = 0; //选择模式,恢复初值 return true; } /*** ** 说明:曝光开始时调用 ***/ bool Detector_TeledyneDalsa::SetXrayOnNum() { Info("--Func-- SetXrayOnNum"); printf("--Func-- SetXrayOnNum \n"); m_bStartGrab = true; //曝光第一次,表示开始采集 m_dwBeginTime = GetTickCount64(); Info("SetXrayOnNum m_dwBeginTime:{$}", m_dwBeginTime); return true; } /*** ** 说明:设置曝光总数 ** TOMO模式根据这个值自动停止采集 ** 参数:nTimes,曝光总数,如果小于0,则不用这个逻辑来停止采集 ***/ bool Detector_TeledyneDalsa::SetExposureTimes(int nTimes) { Info("--Func-- SetExposureTimes({$})", nTimes); //printf("--Func-- SetExposureTimes(%d) \n", nTimes); m_nExposureCount = nTimes; return true; } bool Detector_TeledyneDalsa::PrepareAcquisition(void* pDrvDPC) { printf("PrepareAcquisition \n"); Info("PrepareAcquisition "); bool bRet = false; if ((*m_pDPC2PanelID)[pDrvDPC] != m_nCurrentPanelID) { //printf("Not current DPC, return\n"); Error("Not current DPC, return"); return bRet; } Info("PrepareAcquisition m_nLastLogicMode:{$},m_nCurrentLogicMode:{$}", m_nLastLogicMode, m_nCurrentLogicMode); //模式发生变化,重新加载校正文件 if (m_nLastLogicMode != m_nCurrentLogicMode) { LoadCalibrationFiles(); } //模式发生变化,或还没激活采集,则激活一次 if (m_nLastLogicMode != m_nCurrentLogicMode || GetTeledyneDalsaDPCStatus() != eDetStatus::DetStatus_Acquire) { if (m_strCurrentExamType == "RAD")//PrepareAcquisition { SetEvent(m_hAcqEvent); DWORD dwRet = WaitForSingleObject(m_hAcqReadyEvent, m_nAcqReadyTimeout * 1000); if (dwRet != WAIT_OBJECT_0) { Error("Prepare acquisition failed({$}), cancle it", dwRet); } else { SetTeledyneDalsaDPCStatus(eDetStatus::DetStatus_Acquire); //静态模式激活采集,设置状态 bRet = true; } } else if(m_strCurrentExamType == "PF") { if (!m_cGigeDevice.SetFeature("ReadOutMode", 3)) { Info("Failed to SetFeature ReadOutMode, Reason:({$})", m_cGigeDevice.GetLastStatus()); return false; } if (!m_cGigeDevice.SetFeature("TriggerMode", 1)) { Info("Failed to SetFeature TriggerMode, Reason:({$})", m_cGigeDevice.GetLastStatus()); return false; } if (!m_cGigeDevice.SetFeature("FullWell", 0)) { Info("Failed to SetFeature Fullwell, Reason:({$})", m_cGigeDevice.GetLastStatus()); return false; } Info("Calling StartAcquisition ExamType:{$}", m_strCurrentExamType); Sleep(300); if (!(m_cGigeDevice.GrabAsync(15, G_Teledyne_OnEvent, nullptr))) { Info("Failed to StartAcquisition, Reason:({$})", m_cGigeDevice.GetLastStatus()); return false; } else { SetTeledyneDalsaDPCStatus(eDetStatus::DetStatus_Acquire); //动态模式激活采集,设置状态 } } else if (m_strCurrentExamType == "CF") { if (!m_cGigeDevice.SetFeature("ReadOutMode", 3)) { Info("Failed to SetFeature ReadOutMode, Reason:({$})", m_cGigeDevice.GetLastStatus()); return false; } if (!m_cGigeDevice.SetFeature("TriggerMode", 0)) { Info("Failed to SetFeature TriggerMode, Reason:({$})", m_cGigeDevice.GetLastStatus()); return false; } if (!m_cGigeDevice.SetFeature("FullWell", 0)) { Info("Failed to SetFeature Fullwell, Reason:({$})", m_cGigeDevice.GetLastStatus()); return false; } Info("Calling StartAcquisition ExamType:{$}", m_strCurrentExamType); Sleep(300); if (!(m_cGigeDevice.GrabAsync(5, G_Teledyne_OnEvent, nullptr))) { Info("Failed to StartAcquisition, Reason:({$})", m_cGigeDevice.GetLastStatus()); return false; } else { SetTeledyneDalsaDPCStatus(eDetStatus::DetStatus_Acquire); //动态模式激活采集,设置状态 } } } //FramePrep执行成功,修改记录 if (bRet) { m_nLastLogicMode = m_nCurrentLogicMode; } return true; } bool Detector_TeledyneDalsa::StartAcquisition(void* pDrvDPC) { printf("StartAcquisition \n"); Info("StartAcquisition "); bool bRet = false; if ((*m_pDPC2PanelID)[pDrvDPC] != m_nCurrentPanelID) { //printf("Not current DPC, return\n"); Error("Not current DPC, return"); return bRet; } if (-1 == m_nCurrentLogicMode) { Error("Illegal exam mode"); } else { m_bSendImgToUpper = true; //开始采集,恢复初值 m_bValidImage = false; //开始采集,恢复初值 m_nDropImgNum = 0; //开始采集,恢复初值 bRet = true; m_bFirstImage = true; } //StatusFeedback(EVT_STATUS_PANEL, PANEL_XWINDOW_ON); return bRet; } bool Detector_TeledyneDalsa::StopAcquisition(void* pDrvDPC) { printf("StopAcquisition \n"); Info("StopAcquisition "); bool bRet = false; if ((*m_pDPC2PanelID)[pDrvDPC] != m_nCurrentPanelID) { //printf("Not current DPC, return\n"); Error("Not current DPC, return"); return bRet; } if (eDetStatus::DetStatus_Acquire == GetTeledyneDalsaDPCStatus()) { if (m_nExposureCount > 0 && m_bStartGrab) { //TOMO模式等图 //1.窗口最大1000ms,所以每次等1000ms int nLoop = 0; int nLoopCount = m_nExposureCount - m_nValidImgNum + 2; Info("Exposure count: {$}, valid image count: {$}", m_nExposureCount, m_nValidImgNum); while (m_bStartGrab && (m_nValidImgNum < m_nExposureCount) && (nLoop < nLoopCount)) { DWORD dwRet = WaitForSingleObject(m_hImageEvent, 1000); if (WAIT_TIMEOUT == dwRet) { Info("Waited 1000ms ({$}/{$})", nLoop, nLoopCount); } nLoop++; } } //else //{ // //增加序列模式等图处理 // //1.窗口最大1000ms,所以每次等1000ms // int nLoop = 0; // int nLoopCount = m_nXrayOnNum - m_nValidImgNum + 2; // Info("XrayOn count: %d, valid image count: %d", // m_nXrayOnNum, m_nValidImgNum); // DWORD dwWaitTime = 1000; // while (m_bStartGrab && (m_nValidImgNum < m_nXrayOnNum) && // (nLoop < nLoopCount)) // { // DWORD dwRet = WaitForSingleObject(m_hImageEvent, dwWaitTime); // if (WAIT_TIMEOUT == dwRet) // { // Info("Waited 1000ms(%d/%d)", nLoop, nLoopCount); // } // nLoop++; // } //} Info("Calling StopAcquisition"); if (!m_cGigeDevice.Stop()) { Info("StopAcquisition failed, reason:({$})", m_cGigeDevice.GetLastStatus()); } else { bRet = true; } m_nImgIndex = 0; m_bStartGrab = false; //停止采集,恢复初值 m_nValidImgNum = 0; //停止采集,恢复初值 m_nExposureCount = -1; //停止采集,恢复初值 //m_nXrayOnNum = 0; //停止采集,恢复初值 SetTeledyneDalsaDPCStatus(eDetStatus::DetStatus_Standby); //停止采集,设置状态 } else { Info("Not in acquire status"); //切换到静态采集后,进入了ready状态。但此时可以不开始采集,切换到别的模式, bRet = true; } return bRet; } bool Detector_TeledyneDalsa::StopAcquisitionInside() { printf("StopAcquisitionInside \n"); Info("StopAcquisitionInside "); bool bRet = false; if (eDetStatus::DetStatus_Acquire == GetTeledyneDalsaDPCStatus()) { if (m_nExposureCount > 0 && m_bStartGrab) { //TOMO模式等图 //1.窗口最大1000ms,所以每次等1000ms int nLoop = 0; int nLoopCount = m_nExposureCount - m_nValidImgNum + 2; Info("Exposure count: {$}, valid image count: {$}", m_nExposureCount, m_nValidImgNum); while (m_bStartGrab && (m_nValidImgNum < m_nExposureCount) && (nLoop < nLoopCount)) { DWORD dwRet = WaitForSingleObject(m_hImageEvent, 1000); if (WAIT_TIMEOUT == dwRet) { Info("Waited 1000ms ({$}/{$})", nLoop, nLoopCount); } nLoop++; } } //else //{ // //增加序列模式等图处理 // //1.窗口最大1000ms,所以每次等1000ms // int nLoop = 0; // int nLoopCount = m_nXrayOnNum - m_nValidImgNum + 2; // Info("XrayOn count: %d, valid image count: %d", // m_nXrayOnNum, m_nValidImgNum); // DWORD dwWaitTime = 1000; // while (m_bStartGrab && (m_nValidImgNum < m_nXrayOnNum) && // (nLoop < nLoopCount)) // { // DWORD dwRet = WaitForSingleObject(m_hImageEvent, dwWaitTime); // if (WAIT_TIMEOUT == dwRet) // { // Info("Waited 1000ms(%d/%d)", nLoop, nLoopCount); // } // nLoop++; // } //} Info("Calling StopAcquisition"); if (!m_cGigeDevice.Stop()) { Info("StopAcquisition failed, reason:({$})", m_cGigeDevice.GetLastStatus()); } else { bRet = true; } m_bStartGrab = false; //停止采集,恢复初值 m_nValidImgNum = 0; //停止采集,恢复初值 m_nExposureCount = -1; //停止采集,恢复初值 //m_nXrayOnNum = 0; //停止采集,恢复初值 SetTeledyneDalsaDPCStatus(eDetStatus::DetStatus_Standby); //停止采集,设置状态 } else { Info("Not in acquire status"); //切换到静态采集后,进入了ready状态。但此时可以不开始采集,切换到别的模式, bRet = true; } return bRet; } bool Detector_TeledyneDalsa::ActiveCalibration(void* pDrvDPC, CCOS_CALIBRATION_TYPE eType) { printf("ActiveCalibration \n"); Info("ActiveCalibration "); if ((*m_pDPC2PanelID)[pDrvDPC] != m_nCurrentPanelID) { //printf("Not current DPC, return\n"); Error("Not current DPC, return"); return false; } if (-1 == m_nCurrentLogicMode) { Error("Illegal exam mode"); return false; } if (CCOS_CALIBRATION_TYPE_XRAY == eType) { SetTeledyneDalsaDPCStatus(eDetStatus::DetStatus_XrayCalibration); } m_eCaliType = eType; return true; } /*** ** 校正时响应上层调用的FramePrep ***/ bool Detector_TeledyneDalsa::PrepareCalibration(void* pDrvDPC) { printf("PrepareCalibration \n"); Info("PrepareCalibration "); bool bRet = false; if ((*m_pDPC2PanelID)[pDrvDPC] != m_nCurrentPanelID) { //printf("Not current DPC, return\n"); Error("Not current DPC, return"); return bRet; } if (GetTeledyneDalsaDPCStatus() != eDetStatus::DetStatus_XrayCalibration) { Info("Current status is not XrayCalibration, return succeed"); return true; } if (m_strCurrentExamType == "CF")//PrepareCalibration { //这里应该只在第一次prepare时setevent,但第一次setevent之后,线程一直被占用着, //所以每次setevent也无所谓了,线程执行完毕后resetevent SetEvent(m_hGainEvent); DWORD dwRet = WaitForSingleObject(m_hGainReadyEvent, m_nGainReadyTimeout * 1000); if (dwRet != WAIT_OBJECT_0) { Error("Prepare calibration failed({$}), cancle it", dwRet); } else { bRet = true; } } else { bRet = true; } return bRet; } bool Detector_TeledyneDalsa::StartCalibration(void* pDrvDPC) { printf("StartCalibration \n"); Info("StartCalibration "); bool bRet = false; if ((*m_pDPC2PanelID)[pDrvDPC] != m_nCurrentPanelID) { //printf("Not current DPC, return\n"); Error("Not current DPC, return"); return bRet; } if (CCOS_CALIBRATION_TYPE_DARK == m_eCaliType) { SetEvent(m_hDarkEvent); bRet = true; } else if (CCOS_CALIBRATION_TYPE_XRAY == m_eCaliType) { bRet = StartGainCalibration(); } return bRet; } bool Detector_TeledyneDalsa::StopCalibration(void* pDrvDPC) { printf("StopCalibration \n"); Info("StopCalibration "); bool bRet = false; int nRet = 0; if ((*m_pDPC2PanelID)[pDrvDPC] != m_nCurrentPanelID) { //printf("Not current DPC, return\n"); Error("Not current DPC, return"); return bRet; } Info("StopCalibration Calling StopCalibration"); if (!m_cGigeDevice.Stop()) { Info("StopAcquisition failed, reason:({$})", m_cGigeDevice.GetLastStatus()); } else { bRet = true; } return bRet; } bool Detector_TeledyneDalsa::OpenDetector() { Info("OpenDetector "); bool res; int nDetrNum = 0; if (!m_cGigeDevice.Connect(m_strSerialNum.c_str())) { Info("Detector Connect Failed"); return false; } else { Info("Detector is Connected"); m_eStatus = eDetStatus::DetStatus_Standby; } Info("Open Detector Success--->"); return true; } bool Detector_TeledyneDalsa::CalculateEXI(WORD* pImgData, int nImgWidth, int nImgHeight, int nImageBit, int nThreshold) { int nROIXL = static_cast(0.3 * nImgWidth); int nROIXR = static_cast(0.7 * nImgWidth); int nROIYL = static_cast(0.3 * nImgHeight); int nROIYR = static_cast(0.7 * nImgHeight); WORD* pSrc = NULL; long nCount = 0; DWORD64 nSum = 0; int nEXI = 0; try { for (int i = nROIYL; i < nROIYR; i++) { pSrc = pImgData + (i * nImgWidth); for (int j = nROIXL; j < nROIXR; j++) { nSum += *(pSrc + j); nCount++; } } nEXI = (int)(nSum / nCount); } catch (...) { return false; } Info("Image EXI:{$}, Threshold:{$}", nEXI, nThreshold); if (nEXI >= nThreshold) { Info("Image has xray!"); return true;//有x射线 } return false; } bool Detector_TeledyneDalsa::CheckImageExi(WORD* pImgData, int nImgWidth, int nImgHeight, WORD dwExiThrethold) { if (dwExiThrethold <= 0) { return true; } Info("Check image exi..."); bool bResult = CalculateEXI(pImgData, nImgWidth, nImgHeight, 16, dwExiThrethold); if (bResult) { return true; } Info("Check image exi---black Image"); return false; } //nIndex 缺省-1,当使用缺省值时代表是静态模式,图像名不记录序号 void Detector_TeledyneDalsa::OnProcessImage(int nIndex) { printf("OnProcessImage \n"); Info("OnProcessImage "); CropImageMargin(m_pFullImgBuffer, m_nImageWidth, m_nImageHeight, image.pixels.data(), m_nRawImgWidth, m_nRawImgHeight, 16, m_nCropLeft, m_nCropTop, m_nCropRight, m_nCropBottom); if (!m_bValidImage && m_nDelayTime > 0) { m_dwEndTime = GetTickCount64(); } /*** ** 1.第一个trigIn信号触发trigOut升高,此时代表读图,所以基本需要丢掉第一帧图像 ** 此处灵活应用,可配置丢图张数 ** 2.由于先采集,后曝光,此处还需要根据曝光和拿图时间间隔来判断是否为曝光图像 ****/ Info("OnProcessImage m_nDropImgNum:{$} m_nDropImgCount:{$}", m_nDropImgNum, m_nDropImgCount); if (m_nDropImgNum < m_nDropImgCount)//配置为0时表示不丢图 { m_nDropImgNum++; Info("Drop {$} image", m_nDropImgNum); } else if (!CheckTimeLimit(m_dwBeginTime, m_dwEndTime))//m_nDelayTime 配置为0时表示不延时 { m_nDropImgNum++; Warn("CheckTimeLimit Drop {$} image", m_nDropImgNum); } else { if (m_bIsRadMode)//setacqmode时进行设置 默认logicmode为1时是RAD { Info("OnProcessImage rad mode"); if (m_bSendImgToUpper) { CheckImageExi(m_pFullImgBuffer, m_nImageWidth, m_nImageHeight, m_nExiThreshold);//true 有射线 false 没射线 Info("rad mode send image to upper!"); m_nValidImgNum++; m_bSendImgToUpper = false; //单帧点片,发送一张图像后不再发送图像 DataFeedback(EVT_DATA_RAW_IMAGE, m_pFullImgBuffer); //自动停止采集(发送standby,触发上层流程) StatusFeedback(EVT_STATUS_PANEL, PANEL_END_ACQ); } else { Info("Already send image"); } } else { if (m_bFirstImage) { Info("m_bFirstImage is true"); StatusFeedback(EVT_STATUS_PANEL, PANEL_XWINDOW_ON); m_bFirstImage = false; } Info("OnProcessImage flu mode,m_strCurrentExamType:{$},m_nCurrentLogicMode:{$}", m_strCurrentExamType, m_nCurrentLogicMode); //动态触发模式,但是SetAcqMode的参数是1 if (m_strCurrentExamType != "RAD" && m_nCurrentLogicMode == 1) { Info("m_nCurrentExamType == 8, m_nCurrentLogicMode == 1"); //计算图像EXI 不满足的不往上推 if (!CheckImageExi(m_pFullImgBuffer, m_nImageWidth, m_nImageHeight, m_nExiThreshold)) //true 有射线 false 没射线 { return; } if (m_bValidImage) { //RAD模式已经推过图了就不在推图了 Info("RAD has send image! return"); return; } } m_bValidImage = true; //合法图像,不再判断时间间隔 if (m_nExposureCount > 0 /*&& m_nValidImgNum < m_nExposureCount*/)//3DDR tomo m_nExposureCount消息比图像晚到,影响上图。 { m_nValidImgNum++; ResetEvent(m_hImageEvent); SetEvent(m_hImageEvent); Info("flu mode m_nExposureCount > 0, send image to upper!"); DataFeedback(EVT_DATA_RAW_IMAGE, m_pFullImgBuffer); //TOMO模式根据上层设置的采集总数,自动停止采集(发送standby,触发上层流程) /*if (m_nValidImgNum == m_nExposureCount) { StatusFeedback(EVT_STATUS_PANEL, PANEL_END_ACQ); }*/ } else if(m_nExposureCount == 0) //PF逻辑,不知道曝光次数 { m_nValidImgNum++; ResetEvent(m_hImageEvent); SetEvent(m_hImageEvent); Info("flu mode m_nExposureCount == 0, send image to upper!"); DataFeedback(EVT_DATA_RAW_IMAGE, m_pFullImgBuffer); } } } if (m_bSaveRaw) { Info("Begin save image"); char szTemp[30] = { 0 }; FILE* fp; string strFileName = m_strWorkPath + "\\Image"; if (-1 == nIndex) { strFileName += "\\Image_Rad.raw"; } else { sprintf_s(szTemp, "\\Image_%d.raw", nIndex); strFileName += szTemp; } if ((fp = fopen(strFileName.c_str(), "wb+")) == nullptr) { DWORD dw = GetLastError(); Error("fopen {$} failed, {$}", strFileName.c_str(), dw); return; } fwrite(m_pFullImgBuffer, sizeof(WORD), (ULONGLONG)m_nImageWidth * m_nImageHeight, fp); fclose(fp); Info("Save image over"); } } /*** ** 说明:调用SDK接口,执行offset校正流程 ** dark校正、闲时offset刷新都会调用这个函数 ***/ bool Detector_TeledyneDalsa::StartDarkCalibration(int nLogicMode) { Info("StartDarkCalibration "); bool bRet = false; int nRet = 0, nCurrFrmNum = 0, nPrevFrmNum = nCurrFrmNum - 1; Info("Calling StartDarkCalibration, Logic mode({$})", nLogicMode); if (!m_cGigeDevice.SetFeature("ReadOutMode", 3)) { Info("Failed to SetFeature ReadOutMode, Reason:({$})", m_cGigeDevice.GetLastStatus()); return false; } if (!m_cGigeDevice.SetFeature("TriggerMode", 0)) { Info("Failed to SetFeature TriggerMode, Reason:({$})", m_cGigeDevice.GetLastStatus()); return false; } if (!m_cGigeDevice.SetFeature("FullWell", 0)) { Info("Failed to SetFeature Fullwell, Reason:({$})", m_cGigeDevice.GetLastStatus()); return false; } Info("Calling StartAcquisition ExamType:{$}", m_strCurrentExamType); Sleep(300); if (!(m_cGigeDevice.GrabAsync(5, Dark_Teledyne_OnEvent, nullptr))) { Info("Failed to StartAcquisition, Reason:({$})", m_cGigeDevice.GetLastStatus()); return false; } return true; } bool Detector_TeledyneDalsa::StartGainCalibration() { printf("StartGainCalibration \n"); Info("StartGainCalibration "); if (-1 == m_nCurrentLogicMode) { Error("Illegal exam mode"); return false; } int nCurrFrmNum = 0, nPrevFrmNum = 0; //改为先发状态,再调用SDK接口 //如果后发,SDK接口执行失败会导致不发送这个状态,进而导致停止校正流程不能正确执行 //m_pDrvDPC->SetDetectorStatus(DETECTOR_STATUS_ACQ); //设置状态,准备开始亮场 --ys //m_pCali->SetCalibrationStatus(CCOS_CALIBRATION_STATUS_RUNNING); --ys //静态点片模式的增益校正流程还需要考虑 Info("Calling StartGainCalibration"); if (!m_cGigeDevice.SetFeature("ReadOutMode", 3)) { Info("Failed to SetFeature ReadOutMode, Reason:({$})", m_cGigeDevice.GetLastStatus()); return false; } if (!m_cGigeDevice.SetFeature("TriggerMode", 0)) { Info("Failed to SetFeature TriggerMode, Reason:({$})", m_cGigeDevice.GetLastStatus()); return false; } if (!m_cGigeDevice.SetFeature("FullWell", 0)) { Info("Failed to SetFeature Fullwell, Reason:({$})", m_cGigeDevice.GetLastStatus()); return false; } Info("Calling StartAcquisition ExamType:{$}", m_strCurrentExamType); Sleep(300); if (!(m_cGigeDevice.GrabAsync(5, Gain_Teledyne_OnEvent, nullptr))) { Info("Failed to StartAcquisition, Reason:({$})", m_cGigeDevice.GetLastStatus()); SetTeledyneDalsaDPCStatus(eDetStatus::DetStatus_Standby); StatusFeedback(EVT_STATUS_CALIBRATIOIN, PANEL_EVENT_END_ERROR); return false; } return true; } unsigned __stdcall Detector_TeledyneDalsa::onFPDScanThread(PVOID pvoid) { Detector_TeledyneDalsa* pOpr = (Detector_TeledyneDalsa*)pvoid; Info("Enter scan thread"); //printf("Enter scan thread \r\n"); bool bExit = false; DWORD dwTimeOut = INFINITE; while (!bExit) { DWORD dwRet = WaitForMultipleObjects(SCAN_EVENT_COUNT, pOpr->m_hArrayEvent, FALSE, dwTimeOut); if (WAIT_OBJECT_0 == dwRet) //m_hStopScanEvent { bExit = true; } else if (WAIT_OBJECT_0 + 1 == dwRet) //m_hAcqEvent { pOpr->OnAcquireImage(); } else if (WAIT_OBJECT_0 + 2 == dwRet) //m_hGainEvent { pOpr->OnAcquireGainImage(); } else if (WAIT_OBJECT_0 + 3 == dwRet) //m_hDarkEvent { pOpr->OnStartDarkCalibration(); } else if (WAIT_OBJECT_0 + 4 == dwRet) //m_hProcessImgEvent { pOpr->OnProcessImage(pOpr->m_nImgIndex); } } Info("Level scan thread"); //printf("Level scan thread \r\n"); return 0; } void Detector_TeledyneDalsa::OnAcquireImage() { } void Detector_TeledyneDalsa::OnAcquireGainImage() { } /*** ** 说明:开始暗场校正 ***/ void Detector_TeledyneDalsa::OnStartDarkCalibration() { printf("OnStartDarkCalibration \n"); Info("OnStartDarkCalibration "); SetTeledyneDalsaDPCStatus(eDetStatus::DetStatus_Offset); //开始offset校正 if (StartDarkCalibration(m_nCurrentLogicMode)) { StatusFeedback(EVT_STATUS_CALIBRATIOIN, PANEL_EVENT_END_OK); } else { StatusFeedback(EVT_STATUS_CALIBRATIOIN, PANEL_EVENT_END_ERROR); } SetTeledyneDalsaDPCStatus(eDetStatus::DetStatus_Standby); //offset校正完成,置回Standby } //获取只用于本DPC记录的探测器状态 eDetStatus Detector_TeledyneDalsa::GetTeledyneDalsaDPCStatus() { string strStatus = "Unknown"; switch (m_eStatus) { case eDetStatus::DetStatus_NotIni: strStatus = "NotIni"; break; case eDetStatus::DetStatus_NotConn: strStatus = "NotConn"; break; case eDetStatus::DetStatus_Sleep: strStatus = "Sleep"; break; case eDetStatus::DetStatus_Standby: strStatus = "Standby"; break; case eDetStatus::DetStatus_Work: strStatus = "Work"; break; case eDetStatus::DetStatus_Acquire: strStatus = "Acquire"; break; case eDetStatus::DetStatus_Offset: strStatus = "Offset"; break; case eDetStatus::DetStatus_XrayCalibration: strStatus = "XrayCalibration"; break; default: break; } Info("Driver status: {$}", strStatus.c_str()); return m_eStatus; } //设置只用于本DPC的探测器状态 bool Detector_TeledyneDalsa::SetTeledyneDalsaDPCStatus(eDetStatus status) { string strStatus = "Unknown"; bool bSetStatus = true; switch (status) { case eDetStatus::DetStatus_NotIni: strStatus = "NotIni"; break; case eDetStatus::DetStatus_NotConn: strStatus = "NotConn"; break; case eDetStatus::DetStatus_Sleep: strStatus = "Sleep"; break; case eDetStatus::DetStatus_Standby: strStatus = "Standby"; break; case eDetStatus::DetStatus_Work: strStatus = "Work"; break; case eDetStatus::DetStatus_Acquire: strStatus = "Acquire"; break; case eDetStatus::DetStatus_Offset: strStatus = "Offset"; break; case eDetStatus::DetStatus_XrayCalibration: strStatus = "XrayCalibration"; break; default: bSetStatus = false; break; } if (bSetStatus) { m_eStatus = status; Info("Set driver status: {$}", strStatus.c_str()); } else { Warn("{$} {$} is a illegal status", strStatus.c_str(), (int)status); } return bSetStatus; } bool Detector_TeledyneDalsa::LoadCalibrationFiles() { Info("Calling LoadReference m_nCurrentLogicMode:{$}", m_nCurrentLogicMode); Info("LoadReference command succeed"); return true; } //参照RFOC动态代码整理的图像裁剪功能 int Detector_TeledyneDalsa::CropImageMargin(LPVOID pDstData, int& nDstWidth, int& nDstHeight, LPVOID pScrData, int nSrcWidth, int nSrcHeight, int nBits, int nLeftMargin, int nTopMargin, int nRightMargin, int nBottomMargin) { printf("CropImageMargin \n"); Info("CropImageMargin "); if ((pDstData == NULL) || (pScrData == NULL) || (nSrcWidth <= 0) || (nSrcHeight <= 0) || (nBits <= 0)) return -1; if ((nLeftMargin >= nSrcWidth) || (nTopMargin >= nSrcHeight)) return -1; int nBitsToBYTE = (int)((nBits + 7) * 0.125); if (nBitsToBYTE < 1) return -1; int nXL, nXR, nYL, nYR; nXL = nLeftMargin;//32 nYL = nTopMargin; if (nSrcWidth - nRightMargin < 0) return -1; nXR = nSrcWidth - nRightMargin - 1; //2783 if (nXR < nXL) return -1; if (nSrcHeight - nBottomMargin < 0) return -1; nYR = nSrcHeight - nBottomMargin - 1; if (nYR < nYL) return -1; nDstWidth = nXR - nXL + 1; nDstHeight = nYR - nYL + 1; Info("TopCrop:{$};Bottom:{$},nDstWidth:{$},nDstHeight:{$},Bits:{$}", nYL, nYR, nDstWidth, nDstHeight, nBitsToBYTE); int i = 0; #pragma omp parallel private(i) { #pragma omp for for (i = nYL; i <= nYR; i++) { ::memcpy((WORD*)pDstData + (i - nYL) * nDstWidth, (WORD*)pScrData + (i * nSrcWidth + nXL), nDstWidth * nBitsToBYTE); } } return 0; } /*** ** 说明:非检查界面定时刷新offset的辅助线程 ***/ DWORD __stdcall Detector_TeledyneDalsa::RefreshOffsetThread(PVOID pvoid) { Detector_TeledyneDalsa* pOpr = (Detector_TeledyneDalsa*)pvoid; pOpr->OnRefreshOffset(); return 0; } /*** ** 说明:初始化时刷新所有模式的offset ***/ bool Detector_TeledyneDalsa::RefreshAllOffset() { printf("Refresh all mode offset begin \n"); Info("Refresh all mode offset begin"); //printf("Refresh all mode offset begin... \n"); int nLogicMode; //nLogicMode:配置文件中LogicMode string strFrameRate; int nModeCount = (int)m_ModeConfig["ModeTable"].GetKeyCount("DetectorMode"); SetTeledyneDalsaDPCStatus(eDetStatus::DetStatus_Offset); //开始全模式offset刷新 for (int i = 0; i < nModeCount; i++) { try { //初始化阶段的offset刷新流程不在整个软件的控制之内,所以不会给探测器外触发信号, //因此刷新之前将模式改成内触发重新注册,SDK可同时生成外触发的校正文件 nLogicMode = (int)m_ModeConfig["ModeTable"][i]["LogicMode"];//RefreshAllOffset StartDarkCalibration(nLogicMode); //当前mode失败,仍可以进行下一个mode的刷新 } catch (...) { Fatal("Get configuration crashed!!! OnRefreshOffset over"); SetTeledyneDalsaDPCStatus(eDetStatus::DetStatus_Standby); //offset读取配置失败,置回Standby return false; } } SetTeledyneDalsaDPCStatus(eDetStatus::DetStatus_Standby); //全模式offset刷新结束,置回Standby Info("Refresh all mode offset over"); //printf("Refresh all mode offset over \n"); return true; } /*** ** 说明:非检查界面定时刷新offset ***/ void Detector_TeledyneDalsa::OnRefreshOffset() { printf("OnRefreshOffset begin \n"); Info("OnRefreshOffset begin"); bool bRefresh = false, bReckonTime = true; ULONGLONG fBeginTime, fEndTime; int nAppMode; int nModeCount = 0; // (int)m_ModeConfig["ModeTable"].GetKeyCount("DetectorMode"); int nOftRefreshNum = 1; int nRet = 0, nCurrFrmNum = 0, nPrevFrmNum = nCurrFrmNum - 1; while (!m_bAbortRefreshOft) { if (bReckonTime) //一轮计时完毕,如果仍在检查界面,不会重新计时 { //先计时,超时后刷新offset fBeginTime = GetTickCount64(); fEndTime = fBeginTime; while (!m_bAbortRefreshOft && (fEndTime - fBeginTime) < (ULONGLONG)m_nOftRefreshTimer * 60 * 1000) { fEndTime = GetTickCount64(); Sleep(10); //停10ms再循环,避免CPU占用太高 } Info("offset timmer({$} min)", m_nOftRefreshTimer); bReckonTime = false; //一轮计时完毕,置为false } if (!m_bAbortRefreshOft) { break; } EnterCriticalSection(&m_cs); if (APP_STATUS_WORK_BEGIN == m_nExamMode) { LeaveCriticalSection(&m_cs); bRefresh = false; Sleep(10); //如果当前在检查界面,停10ms再循环,避免CPU占用太高 } else { LeaveCriticalSection(&m_cs); bRefresh = true; } if (bRefresh) { Info("Begin refresh offset {$} time", nOftRefreshNum); //m_pCali->UpdateAutoDarkCalibrationStatus(CCOS_AUTODARKCALIBRATION_STATUS_START); //通知UI开始刷offset SetTeledyneDalsaDPCStatus(eDetStatus::DetStatus_Offset); //开始非检查界面offset刷新 try { nModeCount = (int)m_ModeConfig["ModeTable"].GetKeyCount("DetectorMode"); for (int i = 0; i < nModeCount; i++) { if (!m_bAbortRefreshOft) { break; } EnterCriticalSection(&m_cs); if (APP_STATUS_WORK_BEGIN == m_nExamMode) { LeaveCriticalSection(&m_cs); break; } else { LeaveCriticalSection(&m_cs); } //非检查界面的offset刷新流程不在整个软件的控制之内,所以不会给探测器外触发信号, //因此刷新之前将模式改成内触发重新注册,SDK可同时生成外触发的校正文件 nAppMode = (int)m_ModeConfig["ModeTable"][i]["LogicMode"];//OnRefreshOffset StartDarkCalibration(nAppMode); } } catch (...) { Fatal("Get configuration crashed!!! OnRefreshOffset over"); SetTeledyneDalsaDPCStatus(eDetStatus::DetStatus_Standby); //offset读取配置失败,置回Standby //m_pCali->UpdateAutoDarkCalibrationStatus(CCOS_AUTODARKCALIBRATION_STATUS_END); //通知UI刷offset结束 return; } bRefresh = false; bReckonTime = true; //offset结束,重新计时 SetTeledyneDalsaDPCStatus(eDetStatus::DetStatus_Standby); //非检查界面offset刷新结束,置回Standby //m_pCali->UpdateAutoDarkCalibrationStatus(CCOS_AUTODARKCALIBRATION_STATUS_END); //通知UI刷offset结束 SetEvent(m_hOftEndEvent); //进入检查后,终止闲时offset刷新流程 Info("Refresh offset {$} time over", nOftRefreshNum); nOftRefreshNum++; } } Info("OnRefreshOffset over"); } bool Detector_TeledyneDalsa::CheckTimeLimit(ULONGLONG dwBeginTime, ULONGLONG dwEndTime) { if (m_bValidImage) //合法图像,不再判断时间间隔,直接返回true { Info("CheckTimeLimit m_bValidImage is true!"); return true; } if (m_nDelayTime == 0) //没有开启延时机制 { Info("The delay time is invalid, return"); return true; } if ((int)(dwEndTime - dwBeginTime) > m_nDelayTime) { Info("The interval({$}) is ok", dwEndTime - dwBeginTime); return true; } Warn("The interval({$}) is shorter than the delay({$})",dwEndTime - dwBeginTime, m_nDelayTime); return false; } bool Detector_TeledyneDalsa::GetModeMatchInfo() { return true; } bool Detector_TeledyneDalsa::CallbackProcess(int nEventID, void* context) { Info("CallbackProcess event id:{$}",nEventID); int width, height; unsigned int timestamp; unsigned short* dataptr; switch (nEventID) { case -1: Info("*** Transfer Complete ***"); break; case -2: Error("*** Frame lost in transmission ***"); break; case -3: Error("*** Frame lost in trash buffer ***"); break; case -4: Error("*** Frame Empty ***"); break; default: if (!m_cGigeDevice.GetBufferInfo(nEventID, &dataptr, &width, &height, ×tamp)) { Error("Frame ({$}) receive, Failed to retreive buffer info: ({$})", nEventID, m_cGigeDevice.GetLastStatus()); break; } if (!TXP_FlatfieldCorrection(dataptr, gain.pixels.data(), dark.pixels.data(), raw.pixels.data(), m_dgainAverage, m_nblackOffset, 65536 - 40, width, height)) { Error("FlatfieldCorrection Calibration Failed"); } else { Info("FlatfieldCorrection Calibration Success"); } if (!TXP_DefectCorrection(raw.pixels.data(), defect.pixels.data(), image.pixels.data(), 1416, 1420)) { Error("Defect Calibration Failed"); } else { Info("Defect Calibration Success"); } ResetEvent(m_hProcessImgEvent); SetEvent(m_hProcessImgEvent); m_nImgIndex++; } return true; } bool Detector_TeledyneDalsa::DarkCallbackProcess(int nEventID, void* context) { Info("DrakCallbackProcess EventID:({$})", nEventID); int width, height; unsigned int timestamp; unsigned short* dataptr; switch (nEventID) { case -1: Info("*** Transfer Complete ***"); break; case -2: Error("*** Frame lost in transmission ***"); break; case -3: Error("*** Frame lost in trash buffer ***"); break; case -4: Error("*** Frame Empty ***"); break; default: if (!m_cGigeDevice.GetBufferInfo(nEventID, &dataptr, &width, &height, ×tamp)) { Error("Frame ({$}) receive, Failed to retreive buffer info: ({$})", nEventID, m_cGigeDevice.GetLastStatus()); break; } } return true; } bool Detector_TeledyneDalsa::GainCallbackProcess(int nEventID, void* context) { return false; } void Detector_TeledyneDalsa::ConfFeedback(int nEventID, int nDetectorID, const char* pszMsg, int nParam1, float fParam2, int nPtrParamLen, void* pParam) { if (-1 == nDetectorID) { nDetectorID = m_nCurrentPanelID; } ((FPDDeviceTeledyneDalsa*)(*m_pPanelID2DPC)[nDetectorID])->OnFPDCallback(nDetectorID, nEventID, EVT_LEVEL_CONFIGURATION, pszMsg, nParam1, fParam2, nPtrParamLen, pParam); } void Detector_TeledyneDalsa::InfoFeedback(int nEventID, int nDetectorID, int nParam1, float fParam2, const char* pszMsg, int nPtrParamLen, void* pParam) { if (-1 == nDetectorID) { nDetectorID = m_nCurrentPanelID; } ((FPDDeviceTeledyneDalsa*)(*m_pPanelID2DPC)[nDetectorID])->OnFPDCallback(nDetectorID, nEventID, EVT_LEVEL_INFORMATOION, pszMsg, nParam1, fParam2, nPtrParamLen, pParam); } void Detector_TeledyneDalsa::StatusFeedback(int nEventID, int nParam1, const char* pszMsg, int nDetectorID, float fParam2, int nPtrParamLen, void* pParam) { if (-1 == nDetectorID) { nDetectorID = m_nCurrentPanelID; } ((FPDDeviceTeledyneDalsa*)(*m_pPanelID2DPC)[nDetectorID])->OnFPDCallback(nDetectorID, nEventID, EVT_LEVEL_STATUS, pszMsg, nParam1, fParam2, nPtrParamLen, pParam); } void Detector_TeledyneDalsa::DataFeedback(int nEventID, void* pParam, int nParam1, float fParam2, const char* pszMsg, int nPtrParamLen, int nDetectorID) { if (-1 == nDetectorID) { nDetectorID = m_nCurrentPanelID; } ((FPDDeviceTeledyneDalsa*)(*m_pPanelID2DPC)[nDetectorID])->OnFPDCallback(nDetectorID, nEventID, EVT_LEVEL_DATA, pszMsg, nParam1, fParam2, nPtrParamLen, pParam); } void Detector_TeledyneDalsa::WarnFeedback(int nEventID, const char* pszMsg, int nParam1, float fParam2, int nPtrParamLen, void* pParam, int nDetectorID) { if (-1 == nDetectorID) { nDetectorID = m_nCurrentPanelID; } ((FPDDeviceTeledyneDalsa*)(*m_pPanelID2DPC)[nDetectorID])->OnFPDCallback(nDetectorID, nEventID, EVT_LEVEL_WARNING, pszMsg, nParam1, fParam2, nPtrParamLen, pParam); } void Detector_TeledyneDalsa::ErrorFeedback(int nEventID, const char* pszMsg, int nDetectorID, int nParam1, float fParam2, int nPtrParamLen, void* pParam) { if (-1 == nDetectorID) { nDetectorID = m_nCurrentPanelID; } ((FPDDeviceTeledyneDalsa*)(*m_pPanelID2DPC)[nDetectorID])->OnFPDCallback(nDetectorID, nEventID, EVT_LEVEL_ERROR, pszMsg, nParam1, fParam2, nPtrParamLen, pParam); }