| | |
| | | pDefect->m_bJudge_NG = TRUE; |
| | | pDefect->m_dSizeX_um = dMeasureResult_um; |
| | | pDefect->m_dSizeY_um = dMeasureDiff_um; |
| | | pDefect->m_dChamfer_um = dMeasureResult_um; |
| | | pDefect->m_dChamferOff_um = dMeasureDiff_um; |
| | | pDefect->m_DefectInfo = defect; |
| | | |
| | | if(m_pGrabber->GetSmallImage(iScan,pDefect->m_Image |
| | |
| | | if (glass_id.IsEmpty() == TRUE) |
| | | glass_id.Format(_T("MANUAL_ID")); |
| | | |
| | | // 获取当前产品加载时间 |
| | | CTime tGlassLoading = m_pGlassData->GetLoadingTime(); |
| | | |
| | | CString measure_data; |
| | | CString chip_data; |
| | | CString defect_data; |
| | |
| | | m_pGlassData->GetSideData(DIMENSION_C)->m_nTopCornerHeight, |
| | | m_pGlassData->GetSideData(DIMENSION_C)->m_nBottomCornerWidth, |
| | | m_pGlassData->GetSideData(DIMENSION_C)->m_nBottomCornerHeight |
| | | ); |
| | | ); |
| | | measure_data.Append(_T("\r\n")); |
| | | |
| | | CString measure_file_path; |
| | | if (m_pHardware->m_bSaveResultByHour) { |
| | | // 按小时保存结果 |
| | | measure_file_path.Format(_T("%s\\%s_%02d_MeasureData.csv"), m_strResultFolder, g_pBase->m_strLoadingDay, tGlassLoading.GetHour()); |
| | | } |
| | | else { |
| | | // 不按小时保存结果 |
| | | measure_file_path.Format(_T("%s\\%s_MeasureData.csv"), m_strResultFolder, g_pBase->m_strLoadingDay); |
| | | } |
| | | |
| | | // 获取当前时间 |
| | | std::time_t m_now = std::time(nullptr); |
| | | // 使用localtime_s代替localtime |
| | | std::tm m_nowTm; |
| | | localtime_s(&m_nowTm, &m_now); |
| | | if (m_nowTm.tm_hour < 4) |
| | | { |
| | | measure_file_path.Format(_T("%s\\%s_%02d_MeasureData.csv"), m_strResultFolder, g_pBase->m_strLoadingDay,24); |
| | | } |
| | | else if(m_nowTm.tm_hour > 3 && m_nowTm.tm_hour < 9) |
| | | { |
| | | measure_file_path.Format(_T("%s\\%s_%02d_MeasureData.csv"), m_strResultFolder, g_pBase->m_strLoadingDay, 4); |
| | | } |
| | | else if (m_nowTm.tm_hour > 7 && m_nowTm.tm_hour < 13) |
| | | { |
| | | measure_file_path.Format(_T("%s\\%s_%02d_MeasureData.csv"), m_strResultFolder, g_pBase->m_strLoadingDay, 8); |
| | | } |
| | | else if (m_nowTm.tm_hour > 11 && m_nowTm.tm_hour < 17) |
| | | { |
| | | measure_file_path.Format(_T("%s\\%s_%02d_MeasureData.csv"), m_strResultFolder, g_pBase->m_strLoadingDay, 12); |
| | | } |
| | | else if (m_nowTm.tm_hour > 15 && m_nowTm.tm_hour < 21) |
| | | { |
| | | measure_file_path.Format(_T("%s\\%s_%02d_MeasureData.csv"), m_strResultFolder, g_pBase->m_strLoadingDay, 16); |
| | | } |
| | | else if (m_nowTm.tm_hour > 19) |
| | | { |
| | | measure_file_path.Format(_T("%s\\%s_%02d_MeasureData.csv"), m_strResultFolder, g_pBase->m_strLoadingDay, 20); |
| | | } |
| | | |
| | | |
| | | CheckDirectory(measure_file_path); |
| | | |
| | | CFile measure_module; |
| | |
| | | } |
| | | |
| | | CString Chip_file_path; |
| | | |
| | | localtime_s(&m_nowTm, &m_now); |
| | | if (m_nowTm.tm_hour < 4) |
| | | { |
| | | Chip_file_path.Format(_T("%s\\%s_%02d_ChipData.csv"), m_strResultFolder, g_pBase->m_strLoadingDay,24); |
| | | if (m_pHardware->m_bSaveResultByHour) { |
| | | // 按小时保存结果 |
| | | Chip_file_path.Format(_T("%s\\%s_%02d_ChipData.csv"), m_strResultFolder, g_pBase->m_strLoadingDay, tGlassLoading.GetHour()); |
| | | } |
| | | else if (m_nowTm.tm_hour > 3 && m_nowTm.tm_hour < 9) |
| | | { |
| | | Chip_file_path.Format(_T("%s\\%s_%02d_ChipData.csv"), m_strResultFolder, g_pBase->m_strLoadingDay, 4); |
| | | } |
| | | else if (m_nowTm.tm_hour > 7 && m_nowTm.tm_hour < 13) |
| | | { |
| | | Chip_file_path.Format(_T("%s\\%s_%02d_ChipData.csv"), m_strResultFolder, g_pBase->m_strLoadingDay, 8); |
| | | } |
| | | else if (m_nowTm.tm_hour > 11 && m_nowTm.tm_hour < 17) |
| | | { |
| | | Chip_file_path.Format(_T("%s\\%s_%02d_ChipData.csv"), m_strResultFolder, g_pBase->m_strLoadingDay, 12); |
| | | } |
| | | else if (m_nowTm.tm_hour > 15 && m_nowTm.tm_hour < 21) |
| | | { |
| | | Chip_file_path.Format(_T("%s\\%s_%02d_ChipData.csv"), m_strResultFolder, g_pBase->m_strLoadingDay, 16); |
| | | } |
| | | else if (m_nowTm.tm_hour > 19) |
| | | { |
| | | Chip_file_path.Format(_T("%s\\%s_%02d_ChipData.csv"), m_strResultFolder, g_pBase->m_strLoadingDay, 20); |
| | | else { |
| | | // 不按小时保存结果 |
| | | Chip_file_path.Format(_T("%s\\%s_ChipData.csv"), m_strResultFolder, g_pBase->m_strLoadingDay); |
| | | } |
| | | |
| | | CheckDirectory(Chip_file_path); |
| | |
| | | } |
| | | |
| | | CString Defect_file_path; |
| | | if (m_pHardware->m_bSaveResultByHour) { |
| | | // 按小时保存结果 |
| | | Defect_file_path.Format(_T("%s\\%s_%02d_DefectData.csv"), m_strResultFolder, g_pBase->m_strLoadingDay, tGlassLoading.GetHour()); |
| | | } |
| | | else { |
| | | // 不按小时保存结果 |
| | | Defect_file_path.Format(_T("%s\\%s_DefectData.csv"), m_strResultFolder, g_pBase->m_strLoadingDay); |
| | | } |
| | | |
| | | |
| | | if (m_nowTm.tm_hour < 4) |
| | | { |
| | | Defect_file_path.Format(_T("%s\\%s_%02d_DefectData.csv"), m_strResultFolder, g_pBase->m_strLoadingDay, 24); |
| | | } |
| | | else if (m_nowTm.tm_hour > 3 && m_nowTm.tm_hour < 9) |
| | | { |
| | | Defect_file_path.Format(_T("%s\\%s_%02d_DefectData.csv"), m_strResultFolder, g_pBase->m_strLoadingDay, 4); |
| | | } |
| | | else if (m_nowTm.tm_hour > 7 && m_nowTm.tm_hour < 13) |
| | | { |
| | | Defect_file_path.Format(_T("%s\\%s_%02d_DefectData.csv"), m_strResultFolder, g_pBase->m_strLoadingDay, 8); |
| | | } |
| | | else if (m_nowTm.tm_hour > 11 && m_nowTm.tm_hour < 17) |
| | | { |
| | | Defect_file_path.Format(_T("%s\\%s_%02d_DefectData.csv"), m_strResultFolder, g_pBase->m_strLoadingDay, 12); |
| | | } |
| | | else if (m_nowTm.tm_hour > 15 && m_nowTm.tm_hour < 21) |
| | | { |
| | | Defect_file_path.Format(_T("%s\\%s_%02d_DefectData.csv"), m_strResultFolder, g_pBase->m_strLoadingDay, 16); |
| | | } |
| | | else if (m_nowTm.tm_hour > 19) |
| | | { |
| | | Defect_file_path.Format(_T("%s\\%s_%02d_DefectData.csv"), m_strResultFolder, g_pBase->m_strLoadingDay, 20); |
| | | } |
| | | CheckDirectory(Defect_file_path); |
| | | |
| | | CFile defect_module; |
| | |
| | | BOOL CPostProcess::SaveDefectImage_with_Title(CDefect* pDefect, CSize szImage,CRect rectDefect,CString strFile, CvScalar color) |
| | | { |
| | | Lock(); |
| | | if(pDefect == NULL || pDefect->m_Image == NULL) |
| | | if (pDefect == NULL || pDefect->m_Image == NULL) { |
| | | return FALSE; |
| | | } |
| | | |
| | | // 标题文本 |
| | | CString strTitle; |
| | | int nSideIdx = (0 <= pDefect->m_DefectInfo.m_nSideIdx && pDefect->m_DefectInfo.m_nSideIdx < MAX_SIDE_COUNT) ? pDefect->m_DefectInfo.m_nSideIdx : MAX_SIDE_COUNT; |
| | | int nCategoryIdx = (0 <= pDefect->m_DefectInfo.m_DefectLoc && pDefect->m_DefectInfo.m_DefectLoc < DefectLoc_None) ? pDefect->m_DefectInfo.m_DefectLoc : DefectLoc_Unknown; |
| | | strTitle.Format(_T("SIDE[%s] CAT[%s] SIZE[%d,%d]"), g_SideName[nSideIdx], g_strDefectType[nCategoryIdx], (int)pDefect->m_dSizeX_um, (int)pDefect->m_dSizeY_um); |
| | | |
| | | DefectLocation eCategory = pDefect->m_DefectInfo.m_DefectLoc; |
| | | if (eCategory == DefectLoc_Notch_Dimension || eCategory == DefectLoc_Notch_Chamfer) { |
| | | strTitle.Format(_T("SIDE[%s] CAT[%s] SIZE[%d,%d] distance[%d,%d] "), g_SideName[nSideIdx], g_strDefectType[nCategoryIdx], (int)pDefect->m_dSizeX_um, (int)pDefect->m_dSizeY_um, (int)pDefect->m_dChamfer_um, (int)pDefect->m_dChamferOff_um); |
| | | } |
| | | else { |
| | | strTitle.Format(_T("SIDE[%s] CAT[%s] SIZE[%d,%d]"), g_SideName[nSideIdx], g_strDefectType[nCategoryIdx], (int)pDefect->m_dSizeX_um, (int)pDefect->m_dSizeY_um); |
| | | } |
| | | Unlock(); |
| | | |
| | | // 成功标志 |
| | |
| | | |
| | | // Save Path |
| | | CString strFilePath; |
| | | // 获取当前时间 |
| | | std::time_t m_now = std::time(nullptr); |
| | | // 使用localtime_s代替localtime |
| | | std::tm m_nowTm; |
| | | localtime_s(&m_nowTm, &m_now); |
| | | if (m_nowTm.tm_hour < 4) |
| | | { |
| | | |
| | | strFilePath.Format(_T("D:\\Data\\%s\\%s\\%d\\%02d\\%02d\\%s_%s_%02d.csv"), m_pHardware->GetMachineName(), m_pHardware->GetLineID() |
| | | , tLoadingTime.GetYear(), tLoadingTime.GetMonth(), tLoadingTime.GetDay() |
| | | , m_pGlassData->GetGlassRecipe()->GetRecipeName(), tLoadingTime.Format(_T("%Y%m%d")),24 ); |
| | | if (m_pHardware->m_bSaveResultByHour) { |
| | | // 按小时保存,绑定玻璃 Loading Time |
| | | strFilePath.Format(_T("D:\\Data\\%s\\%s\\%d\\%02d\\%02d\\%s_%s_%02d.csv"), |
| | | m_pHardware->GetMachineName(), |
| | | m_pHardware->GetLineID(), |
| | | tLoadingTime.GetYear(), |
| | | tLoadingTime.GetMonth(), |
| | | tLoadingTime.GetDay(), |
| | | g_pBase->m_strRecipeName, |
| | | g_pBase->m_strLoadingDay, |
| | | tLoadingTime.GetHour()); |
| | | } |
| | | else if (m_nowTm.tm_hour > 3 && m_nowTm.tm_hour < 8) |
| | | { |
| | | strFilePath.Format(_T("D:\\Data\\%s\\%s\\%d\\%02d\\%02d\\%s_%s_%02d.csv"), m_pHardware->GetMachineName(), m_pHardware->GetLineID() |
| | | , tLoadingTime.GetYear(), tLoadingTime.GetMonth(), tLoadingTime.GetDay() |
| | | , m_pGlassData->GetGlassRecipe()->GetRecipeName(), tLoadingTime.Format(_T("%Y%m%d")), 4); |
| | | } |
| | | else if (m_nowTm.tm_hour > 7 && m_nowTm.tm_hour < 12) |
| | | { |
| | | strFilePath.Format(_T("D:\\Data\\%s\\%s\\%d\\%02d\\%02d\\%s_%s_%02d.csv"), m_pHardware->GetMachineName(), m_pHardware->GetLineID() |
| | | , tLoadingTime.GetYear(), tLoadingTime.GetMonth(), tLoadingTime.GetDay() |
| | | , m_pGlassData->GetGlassRecipe()->GetRecipeName(), tLoadingTime.Format(_T("%Y%m%d")), 8); |
| | | } |
| | | else if (m_nowTm.tm_hour > 11 && m_nowTm.tm_hour < 16) |
| | | { |
| | | strFilePath.Format(_T("D:\\Data\\%s\\%s\\%d\\%02d\\%02d\\%s_%s_%02d.csv"), m_pHardware->GetMachineName(), m_pHardware->GetLineID() |
| | | , tLoadingTime.GetYear(), tLoadingTime.GetMonth(), tLoadingTime.GetDay() |
| | | , m_pGlassData->GetGlassRecipe()->GetRecipeName(), tLoadingTime.Format(_T("%Y%m%d")), 12); |
| | | } |
| | | else if (m_nowTm.tm_hour > 15 && m_nowTm.tm_hour < 20) |
| | | { |
| | | strFilePath.Format(_T("D:\\Data\\%s\\%s\\%d\\%02d\\%02d\\%s_%s_%02d.csv"), m_pHardware->GetMachineName(), m_pHardware->GetLineID() |
| | | , tLoadingTime.GetYear(), tLoadingTime.GetMonth(), tLoadingTime.GetDay() |
| | | , m_pGlassData->GetGlassRecipe()->GetRecipeName(), tLoadingTime.Format(_T("%Y%m%d")), 16); |
| | | } |
| | | else if (m_nowTm.tm_hour > 19) |
| | | { |
| | | strFilePath.Format(_T("D:\\Data\\%s\\%s\\%d\\%02d\\%02d\\%s_%s_%02d.csv"), m_pHardware->GetMachineName(), m_pHardware->GetLineID() |
| | | , tLoadingTime.GetYear(), tLoadingTime.GetMonth(), tLoadingTime.GetDay() |
| | | , m_pGlassData->GetGlassRecipe()->GetRecipeName(), tLoadingTime.Format(_T("%Y%m%d")), 20); |
| | | else { |
| | | // 按天保存,绑定玻璃 Loading Time |
| | | strFilePath.Format(_T("D:\\Data\\%s\\%s\\%d\\%02d\\%02d\\%s_%s.csv"), |
| | | m_pHardware->GetMachineName(), |
| | | m_pHardware->GetLineID(), |
| | | tLoadingTime.GetYear(), |
| | | tLoadingTime.GetMonth(), |
| | | tLoadingTime.GetDay(), |
| | | g_pBase->m_strRecipeName, |
| | | g_pBase->m_strLoadingDay); |
| | | } |
| | | |
| | | CheckDirectory(strFilePath); |
| | |
| | | |
| | | m_dSizeX_um = 0.0; |
| | | m_dSizeY_um = 0.0; |
| | | m_dChamfer_um = 0.0; |
| | | m_dChamferOff_um = 0.0; |
| | | |
| | | m_nDefectMergeCount = 0; |
| | | m_bDefectMergeRemoved = FALSE; |
| | |
| | | |
| | | double m_dSizeX_um; |
| | | double m_dSizeY_um; |
| | | double m_dChamfer_um; |
| | | double m_dChamferOff_um; |
| | | |
| | | // Merge |
| | | int m_nDefectMergeCount; |
| | |
| | | |
| | | BOOL CInspectCamera::Notch_Process(int iThread,DimensionDir emDim, stFrameIndex stFrame) |
| | | { |
| | | //CTime tCurrentTime = CTime::GetCurrentTime(); |
| | | //CTime tLimitTime = CTime(2023,3,31,11,59,59); |
| | | //CTimeSpan tSpanTime = tLimitTime - tCurrentTime; |
| | | |
| | | //if(tSpanTime.GetTotalSeconds() < 0) |
| | | // return FALSE; |
| | | |
| | | if(m_pGlassData == NULL) |
| | | return FALSE; |
| | | |
| | |
| | | pEdgeImage = cvCloneImage(pOriginImage); |
| | | pBinImage = cvCloneImage(pOriginImage); |
| | | |
| | | g_pLog->DisplayMessage(_T("1. Notch_Process %s : %d, idx %d"),g_SideName[(int) emDim], stFrame.nFrameIdx,i); |
| | | |
| | | // 1. Image PreProcess.. |
| | | g_pLog->DisplayMessage(_T("1. Notch_Process %s : %d, idx %d"), g_SideName[(int)emDim], stFrame.nFrameIdx, i); |
| | | Notch_Process_PreProcess(emDim, stFrame, i, pOriginImage, pEdgeImage, pBinImage, rtRotateArea); |
| | | // Notch_Process_PreProcess_2(emDim, stFrame, i, pOriginImage, pEdgeImage, pBinImage, rtRotateArea); |
| | | |
| | | g_pLog->DisplayMessage(_T("2. Notch_Process %s : %d, idx %d"),g_SideName[(int) emDim], stFrame.nFrameIdx,i); |
| | | |
| | | // 2. Notch Dimension/Chamfer Find.. |
| | | g_pLog->DisplayMessage(_T("2. Notch_Process %s : %d, idx %d"), g_SideName[(int)emDim], stFrame.nFrameIdx, i); |
| | | Notch_Process_Measure(emDim, stFrame, i, pOriginImage, pEdgeImage, pBinImage, rtRotateArea); |
| | | |
| | | g_pLog->DisplayMessage(_T("3. Notch_Process %s : %d, idx %d"),g_SideName[(int) emDim], stFrame.nFrameIdx,i); |
| | | |
| | | // 3. Notch Dimension/Chamfer Calculate Result.. |
| | | g_pLog->DisplayMessage(_T("3. Notch_Process %s : %d, idx %d"), g_SideName[(int)emDim], stFrame.nFrameIdx, i); |
| | | bool bResult = Notch_Process_Calculate(emDim, stFrame, i, pOriginImage, pEdgeImage, pBinImage, rtRotateArea); |
| | | |
| | | g_pLog->DisplayMessage(_T("4. Notch_Process %s : %d, idx %d"),g_SideName[(int) emDim], stFrame.nFrameIdx,i); |
| | | // 4. Notch Dimension/Chamfer Judge |
| | | g_pLog->DisplayMessage(_T("4. Notch_Process %s : %d, idx %d"), g_SideName[(int)emDim], stFrame.nFrameIdx, i); |
| | | Notch_Process_Judge(emDim, stFrame, i, pOriginImage, pEdgeImage, pBinImage, rtRotateArea); |
| | | |
| | | if (!bResult) |
| | |
| | | |
| | | pSideData->m_bNotchInspection_Complete = TRUE; |
| | | |
| | | |
| | | |
| | | return FALSE; |
| | | } |
| | | |
| | | g_pLog->DisplayMessage(_T("5. Notch_Process %s : %d, idx %d"),g_SideName[(int) emDim], stFrame.nFrameIdx,i); |
| | | // 5. Notch Defect Inspect (Chip/Crack) |
| | | g_pLog->DisplayMessage(_T("5. Notch_Process %s : %d, idx %d"), g_SideName[(int)emDim], stFrame.nFrameIdx, i); |
| | | Notch_Process_Defect(emDim, stFrame, i, pOriginImage, pEdgeImage, pBinImage, rtRotateArea); |
| | | |
| | | g_pLog->DisplayMessage(_T("6. Notch_Process %s : %d, idx %d"),g_SideName[(int) emDim], stFrame.nFrameIdx,i); |
| | | // 6. Notch Find Circle |
| | | g_pLog->DisplayMessage(_T("6. Notch_Process %s : %d, idx %d"), g_SideName[(int)emDim], stFrame.nFrameIdx, i); |
| | | Notch_Process_FindCircle(emDim, stFrame, i); |
| | | |
| | | // 7. Notch Process End |
| | | g_pLog->DisplayMessage(_T("7. Notch_Process %s : %d, idx %d"),g_SideName[(int) emDim], stFrame.nFrameIdx,i); |
| | | |
| | | cvReleaseImageHeader(&pOriginImage); |
| | | cvReleaseImage(&pEdgeImage); |
| | | cvReleaseImage(&pBinImage); |
| | |
| | | |
| | | pSideData->m_bNotchInspection_Complete = TRUE; |
| | | |
| | | g_pLog->DisplayMessage(_T("7. Notch_Process End %s : %d"),g_SideName[(int) emDim], stFrame.nFrameIdx); |
| | | |
| | | return TRUE; |
| | | } |
| | | |
| | | void CInspectCamera::Notch_Process_PreProcess(DimensionDir emDim, stFrameIndex stFrame, int nNotchIdx, IplImage* scr, IplImage* img_Edge, IplImage* img_Bin, CRect rtROI) |
| | | { |
| | | if(m_pRecipe == NULL) |
| | | if (m_pRecipe == nullptr) { |
| | | return; |
| | | } |
| | | |
| | | if(nNotchIdx < 0 || MAX_SIDE_NOTCH_COUNT <= nNotchIdx) |
| | | if (nNotchIdx < 0 || nNotchIdx >= MAX_SIDE_NOTCH_COUNT) { |
| | | return; |
| | | } |
| | | |
| | | CString strTemp; |
| | | // 中值滤波器大小,用于去噪,必须为奇数(若偶数会自动减1) |
| | | const int nSmoothFilter = m_pRecipe->m_SideParam[(int)emDim].m_NotchPrm[nNotchIdx].m_nSmooth_Filter; |
| | | |
| | | int sigma1 = m_pRecipe->m_SideParam[(int) emDim].m_NotchPrm[nNotchIdx].m_nSmooth_Filter; |
| | | int sigma2 = 7; |
| | | // 磨边区域阈值,控制反二值化阈值,主要用于提取 Notch 边缘特征 |
| | | const int nGrindThreshold = m_pRecipe->m_SideParam[(int)emDim].m_NotchPrm[nNotchIdx].m_nGrind_Threshold; |
| | | |
| | | if(sigma1 % 2 == 0) |
| | | sigma1 = sigma1 - 1; |
| | | // 玻璃区域阈值,控制正二值化阈值,用于提取玻璃主体区域 |
| | | const int nGlassThreshold = m_pRecipe->m_SideParam[(int)emDim].m_NotchPrm[nNotchIdx].m_nGlass_Threshold; |
| | | |
| | | if(1 < sigma1) |
| | | cvSmooth(scr,img_Bin,CV_MEDIAN,sigma1); |
| | | // 确保奇数滤波器大小 |
| | | int nFilterSize = (nSmoothFilter % 2 == 0) ? (nSmoothFilter - 1) : nSmoothFilter; |
| | | |
| | | // double th1 = (double) m_pRecipe->m_SideParam[(int) emDim].m_NotchPrm[nNotchIdx].m_nGrind_Threshold * 10; |
| | | // double th2 = 40.0; |
| | | // int sigma=5; |
| | | // |
| | | // cvCanny(img_Bin,img_Edge,th1,th2,sigma); |
| | | if (nFilterSize > 1) { |
| | | // 中值滤波降噪 |
| | | cvSmooth(scr, img_Bin, CV_MEDIAN, nFilterSize); |
| | | } |
| | | |
| | | double th1 = (double) m_pRecipe->m_SideParam[(int) emDim].m_NotchPrm[nNotchIdx].m_nGrind_Threshold; |
| | | // Edge图:反二值化阈值处理 |
| | | cvThreshold(scr, img_Edge, nGrindThreshold, 255, CV_THRESH_BINARY_INV); |
| | | CString strEdgeFileName; |
| | | strEdgeFileName.Format(_T("Notch\\Notch_%d_Edge.jpg"), nNotchIdx); |
| | | SaveDebugImage(emDim, stFrame, img_Edge, strEdgeFileName); |
| | | |
| | | cvThreshold(scr,img_Edge,th1,255,CV_THRESH_BINARY_INV); |
| | | |
| | | strTemp.Format(_T("Notch\\Notch_%d_Edge.jpg"), nNotchIdx); |
| | | SaveDebugImage(emDim, stFrame, img_Edge, strTemp); |
| | | |
| | | th1 = m_pRecipe->m_SideParam[(int) emDim].m_NotchPrm[nNotchIdx].m_nGlass_Threshold; |
| | | |
| | | cvThreshold(scr,img_Bin,th1,255,CV_THRESH_BINARY); |
| | | |
| | | strTemp.Format(_T("Notch\\Notch_%d_Bin.jpg"), nNotchIdx); |
| | | SaveDebugImage(emDim, stFrame, img_Bin, strTemp); |
| | | } |
| | | |
| | | void CInspectCamera::Notch_Process_PreProcess_2(DimensionDir emDim, stFrameIndex stFrame, int nNotchIdx, IplImage* scr, IplImage* img_Edge, IplImage* img_Bin, CRect rtROI) |
| | | { |
| | | if(m_pRecipe == NULL) |
| | | return; |
| | | |
| | | if(nNotchIdx < 0 || MAX_SIDE_NOTCH_COUNT <= nNotchIdx) |
| | | return; |
| | | |
| | | int sigma1 = m_pRecipe->m_SideParam[(int) emDim].m_NotchPrm[nNotchIdx].m_nSmooth_Filter; |
| | | |
| | | CString strTemp; |
| | | cvThreshold(scr,img_Edge,sigma1,255,CV_THRESH_BINARY_INV); |
| | | |
| | | double th1 = (double) m_pRecipe->m_SideParam[(int) emDim].m_NotchPrm[nNotchIdx].m_nGrind_Threshold; |
| | | double th2 = 40.0; |
| | | int sigma=5; |
| | | |
| | | cvCanny(img_Edge, img_Edge,th1,th2,sigma); |
| | | |
| | | strTemp.Format(_T("Notch\\Notch_%d_Edge.jpg"), nNotchIdx); |
| | | SaveDebugImage(emDim, stFrame, img_Edge, strTemp); |
| | | |
| | | th1 = m_pRecipe->m_SideParam[(int) emDim].m_NotchPrm[nNotchIdx].m_nGlass_Threshold; |
| | | |
| | | cvThreshold(scr,img_Bin,th1,255,CV_THRESH_BINARY); |
| | | |
| | | strTemp.Format(_T("Notch\\Notch_%d_Bin.jpg"), nNotchIdx); |
| | | SaveDebugImage(emDim, stFrame, img_Bin, strTemp); |
| | | // Bin图:正常二值化 |
| | | cvThreshold(scr, img_Bin, nGlassThreshold, 255, CV_THRESH_BINARY); |
| | | CString strBinFileName; |
| | | strBinFileName.Format(_T("Notch\\Notch_%d_Bin.jpg"), nNotchIdx); |
| | | SaveDebugImage(emDim, stFrame, img_Bin, strBinFileName); |
| | | } |
| | | |
| | | void CInspectCamera::Notch_Process_Measure(DimensionDir emDim, stFrameIndex stFrame, int nNotchIdx, IplImage* scr,IplImage* img_Edge,IplImage* img_Bin, CRect rtROI) |
| | |
| | | break; |
| | | } |
| | | |
| | | |
| | | if(bEdgeCheck == FALSE && (bEdgeFind == TRUE || bBinEdgeFind == TRUE)) |
| | | { |
| | | if(bFindEdge == FALSE && bEdgeFind == TRUE) |
| | |
| | | CPoint ptDim_pxl = m_pGlassData->GetSideData(emDim)->m_ptNotch_Dimension_Edge[nNotchIdx][nMeasureIdx]; |
| | | CPoint ptChamfer_pxl = m_pGlassData->GetSideData(emDim)->m_ptNotch_Chamfer_Edge[nNotchIdx][nMeasureIdx]; |
| | | |
| | | if (ptRef_pxl.x < 0 || ptRef_pxl.y < 0) { |
| | | g_pLog->DisplayMessage(_T("[ERROR] Invalid Ref Point at Notch_Process_Calculate, NotchIdx: %d, MeasureIdx: %d, Point: (%d, %d)"), nNotchIdx, nMeasureIdx, ptRef_pxl.x, ptRef_pxl.y); |
| | | continue; |
| | | } |
| | | |
| | | if (ptDim_pxl.x < 0 || ptDim_pxl.y < 0) { |
| | | g_pLog->DisplayMessage(_T("[ERROR] Invalid Dim Point at Notch_Process_Calculate, NotchIdx: %d, MeasureIdx: %d, Point: (%d, %d)"), nNotchIdx, nMeasureIdx, ptDim_pxl.x, ptDim_pxl.y); |
| | | continue; |
| | | } |
| | | |
| | | if (ptChamfer_pxl.x < 0 || ptChamfer_pxl.y < 0) { |
| | | g_pLog->DisplayMessage(_T("[ERROR] Invalid Chamfer Point at Notch_Process_Calculate, NotchIdx: %d, MeasureIdx: %d, Point: (%d, %d)"), nNotchIdx, nMeasureIdx, ptChamfer_pxl.x, ptChamfer_pxl.y); |
| | | continue; |
| | | } |
| | | |
| | | // Dimension |
| | | double dX_dim_um = (double)(ptRef_pxl.x - ptDim_pxl.x) * m_dPixelSizeX; |
| | | double dY_dim_um = (double)(ptRef_pxl.y - ptDim_pxl.y) * m_dPixelSizeY; |
| | |
| | | |
| | | m_pGlassData->GetSideData(emDim)->m_dNotch_Chamfer_Edge_Result_um[nNotchIdx][nMeasureIdx] = dChamfer; |
| | | |
| | | if (dDimension > 2000 && dChamfer > 2000) |
| | | { |
| | | return FALSE; |
| | | if (dDimension > 2000.0 && dChamfer > 2000.0) { |
| | | g_pLog->DisplayMessage(_T("[ERROR] Abnormal Dimension & Chamfer too large at Notch_Process_Calculate, NotchIdx: %d, MeasureIdx: %d, Dimension: %.2f, Chamfer: %.2f"), nNotchIdx, nMeasureIdx, dDimension, dChamfer); |
| | | continue; |
| | | } |
| | | } |
| | | |
| | |
| | | //选取测量研磨尺寸最大值 |
| | | if (m_nChamferOffset_um < dChamfer_um) |
| | | { |
| | | m_nChamferOffset_um = dChamfer_um; |
| | | |
| | | m_nChamferOffset_um = dChamfer_um; |
| | | } |
| | | m_pGlassData->GetSideData(emDim)->m_dNotch_Chamfer_Edge_Result_Diff_um[nNotchIdx][nMeasureIdx] = dChamfer_std_um - dChamfer_um; |
| | | m_pGlassData->GetSideData(emDim)->m_dNotch_Chamfer_Edge_Judge_Std_um[nNotchIdx][nMeasureIdx] = dChamfer_std_um; |
| | |
| | | |
| | | CString strTemp; |
| | | |
| | | |
| | | int nSide = (int) emDim; |
| | | int nThreshold = pNotchParam->m_nNotch_Inspect_Defect_Threshold; |
| | | int nOffset = pNotchParam->m_nNotch_Inspect_Defect_Offset; |
| | |
| | | vecDefectCandidateList.push_back(defectInfo); |
| | | } |
| | | m_pDefectControl->ExtractDefect_Notch(emDim, m_iCamera, stFrame.nScanIdx, nNotchIdx, &vecDefectCandidateList); |
| | | #else |
| | | |
| | | #else |
| | | nOffset = m_nChamferOffset_um / m_pGlassData->GetSideData(emDim)->m_dPixelSizeX; |
| | | nOffset += pNotchParam->m_nNotch_Inspect_Defect_Offset; |
| | | m_nChamferOffset_um = 0; |
| | |
| | | CRect rtSet_Area = pNotchParam->m_rtNotch_Circle_Area_pxl[nCircleIdx]; |
| | | |
| | | CRect rtRotateArea; |
| | | |
| | | if(GetAlignRotate(emDim, ptSet_TopMark, ptSet_BotMark, rtSet_Area, rtRotateArea) == FALSE) |
| | | if (GetAlignRotate(emDim, ptSet_TopMark, ptSet_BotMark, rtSet_Area, rtRotateArea) == FALSE) { |
| | | g_pLog->DisplayMessage(_T("Notch Circle %d Rotate Area Error"), nCircleIdx); |
| | | continue; |
| | | } |
| | | |
| | | CRect rtROI = rtRotateArea; |
| | | if (rtROI.Width() <= 0 || rtROI.Height() <= 0) { |
| | | g_pLog->DisplayMessage(_T("Invalid ROI size: %d x %d"), rtROI.Width(), rtROI.Height()); |
| | | continue; |
| | | } |
| | | pSideData->m_rtNotchCircleArea_pxl[nNotchIdx][nCircleIdx] = rtROI; |
| | | |
| | | VectorDouble vectorX; |
| | | VectorDouble vectorY; |
| | | VectorDouble vectorR; |
| | | |
| | | /* |
| | | for(int nMeasureIdx=0; nMeasureIdx<MAX_SIDE_NOTCH_MEASURE_COUNT; nMeasureIdx++) |
| | | { |
| | | if(pSideData->m_nNotch_Dimension_Edge_Judge[nMeasureIdx] ==0) |
| | | continue; |
| | | |
| | | vectorX.push_back((double) pSideData->m_ptNotch_Dimension_Edge[nNotchIdx][nMeasureIdx].x); |
| | | vectorY.push_back((double) pSideData->m_ptNotch_Dimension_Edge[nNotchIdx][nMeasureIdx].y); |
| | | } |
| | | */ |
| | | |
| | | // 2. Get Edge Line |
| | | int nThreshold = m_pRecipe->m_SideParam[(int) emDim].m_nChamferLineThreshold; |
| | |
| | | IplImage* pEdgeImage = cvCreateImage(cvSize(rtROI.Width(), rtROI.Height()), 8, 1); |
| | | IplImage* pCannyEdgeImage = cvCreateImage(cvSize(rtROI.Width(), rtROI.Height()), 8, 1); |
| | | |
| | | for(int i=0; i<rtROI.Height(); i++) |
| | | memcpy(&pEdgeImage->imageData[(i*pEdgeImage->widthStep)], (pFrameBuffer + ((rtROI.top+i)*m_nFrameWidth) + rtROI.left), rtROI.Width()); |
| | | for (int i = 0; i < rtROI.Height(); i++) { |
| | | memcpy(&pEdgeImage->imageData[(i * pEdgeImage->widthStep)], (pFrameBuffer + ((rtROI.top + i) * m_nFrameWidth) + rtROI.left), rtROI.Width()); |
| | | } |
| | | |
| | | int sigma1 = m_pRecipe->m_SideParam[(int) emDim].m_NotchPrm[nNotchIdx].m_nSmooth_Filter; |
| | | int nMedianFilterSize = m_pRecipe->m_SideParam[(int)emDim].m_NotchPrm[nNotchIdx].m_nSmooth_Filter; |
| | | nMedianFilterSize = std::max(3, std::min(nMedianFilterSize, 31)); |
| | | if (nMedianFilterSize % 2 == 0) { |
| | | nMedianFilterSize--; |
| | | } |
| | | cvSmooth(pEdgeImage, pEdgeImage, CV_MEDIAN, nMedianFilterSize); |
| | | |
| | | if(sigma1 % 2 == 0) |
| | | sigma1 = sigma1 - 1; |
| | | double th1 = 40.0; |
| | | double th2 = std::max(1.0, std::min((double)m_pRecipe->m_SideParam[(int)emDim].m_NotchPrm[nNotchIdx].m_nGrind_Threshold * 10, 255.0)); |
| | | |
| | | if(1 < sigma1) |
| | | cvSmooth(pEdgeImage,pEdgeImage,CV_MEDIAN,sigma1); |
| | | if (th1 > th2) { |
| | | std::swap(th1, th2); |
| | | } |
| | | |
| | | double th1 = (double) m_pRecipe->m_SideParam[(int) emDim].m_NotchPrm[nNotchIdx].m_nGrind_Threshold * 10; |
| | | double th2 = 40.0; |
| | | int sigma=5; |
| | | g_pLog->DisplayMessage(_T("Smooth Filter: %d, Canny th1: %.1f, th2: %.1f"), nMedianFilterSize, th1, th2); |
| | | |
| | | cvCanny(pEdgeImage,pCannyEdgeImage,th1,th2,sigma); |
| | | cvCanny(pEdgeImage, pCannyEdgeImage, th1, th2, nMedianFilterSize); |
| | | |
| | | CString strTemp; |
| | | strTemp.Format(_T("Notch\\Notch_%d_Circle_%d_Ori.jpg"), nNotchIdx, nCircleIdx); |
| | |
| | | { |
| | | sprintf(pSideData->m_strNotchCircle_Radius_Comment[nNotchIdx][nCircleIdx], "Rad. [OK] %.1f um / %.1f um", dRadiuse_um, dResult_um); |
| | | } |
| | | |
| | | } |
| | | } |
| | | } |
| | |
| | | return TRUE; |
| | | } |
| | | |
| | | |
| | | |
| | | BOOL CInspectCamera::Measure_TopCorner_RCut(int iThread,DimensionDir emDim, stFrameIndex stFrame) |
| | | { |
| | | if(m_pGlassData == NULL || m_pRecipe == NULL) |
| | |
| | | |
| | | BOOL CInspectCamera::OnThreadEnd(int iThread, CInspectThread *pInspectThread) |
| | | { |
| | | |
| | | return TRUE; |
| | | } |
| | | |
| | | BOOL CInspectCamera::OnThreadEndAll() |
| | | { |
| | | |
| | | return TRUE; |
| | | } |
| | | |
| | |
| | | |
| | | m_bUse_SaveDebugImage = rhs.m_bUse_SaveDebugImage; |
| | | |
| | | // ly,2025.07.10 |
| | | m_bSaveResultByHour = rhs.m_bSaveResultByHour; |
| | | |
| | | // ly,2025.07.07 |
| | | m_bEnableAutoCopy = rhs.m_bEnableAutoCopy; |
| | | m_strCopyToolExePath = rhs.m_strCopyToolExePath; |
| | |
| | | else if((void *)&m_nSaveImageQuality == pValue) |
| | | str = _T("SAVEIMAGE_QUALITY"); |
| | | |
| | | // ly,2025.07.10 |
| | | else if ((void*)&m_bSaveResultByHour == pValue) |
| | | str = _T("SAVE_RESULT_BY_HOUR"); |
| | | |
| | | // ly,2025.07.07 |
| | | else if ((void*)&m_bEnableAutoCopy == pValue) |
| | | str = _T("ENABLE_AUTOCOPY"); |
| | |
| | | BasicInfoFile.GetItemValue((TCHAR*)(LPCTSTR)str,nTemp); |
| | | m_bUse_SaveDebugImage = (BOOL) nTemp; |
| | | |
| | | // ly.2025.07.07 |
| | | // ly,2025.07.10 |
| | | str = GetFileString((void*)&m_bSaveResultByHour); |
| | | if (str.IsEmpty() == TRUE) |
| | | return FALSE; |
| | | BasicInfoFile.GetItemValue((TCHAR*)(LPCTSTR)str, m_bSaveResultByHour, FALSE); |
| | | |
| | | // ly,2025.07.07 |
| | | str = GetFileString((void*)&m_bEnableAutoCopy); |
| | | if (str.IsEmpty() == TRUE) |
| | | return FALSE; |
| | |
| | | Register.GetItemValue((TCHAR*)(LPCTSTR)str,nTemp); |
| | | m_bUse_SaveDebugImage = (BOOL) nTemp; |
| | | |
| | | // ly.2025.07.07 |
| | | // ly,2025.07.10 |
| | | str = GetFileString((void*)&m_bSaveResultByHour); |
| | | if (str.IsEmpty() == TRUE) |
| | | return FALSE; |
| | | Register.GetItemValue((TCHAR*)(LPCTSTR)str, m_bSaveResultByHour, FALSE); |
| | | |
| | | // ly,2025.07.07 |
| | | str = GetFileString((void*)&m_bEnableAutoCopy); |
| | | if (str.IsEmpty() == TRUE) |
| | | return FALSE; |
| | |
| | | return FALSE; |
| | | Register.SetItemValue((TCHAR*)(LPCTSTR)str,(int) m_bUse_SaveDebugImage); |
| | | |
| | | // ly.2025.07.07 |
| | | // ly,2025.07.10 |
| | | str = GetFileString((void*)&m_bSaveResultByHour); |
| | | if (str.IsEmpty() == TRUE) |
| | | return FALSE; |
| | | Register.SetItemValue((TCHAR*)(LPCTSTR)str, (int)m_bSaveResultByHour); |
| | | |
| | | // ly,2025.07.07 |
| | | str = GetFileString((void*)&m_bEnableAutoCopy); |
| | | if (str.IsEmpty() == TRUE) |
| | | return FALSE; |
| | |
| | | return FALSE; |
| | | BasicInfoFile.SetItemValue((TCHAR*)(LPCTSTR)str,m_bUse_SaveDebugImage); |
| | | |
| | | // ly.2025.07.07 |
| | | // ly,2025.07.10 |
| | | str = GetFileString((void*)&m_bSaveResultByHour); |
| | | if (str.IsEmpty() == TRUE) |
| | | return FALSE; |
| | | BasicInfoFile.SetItemValue((TCHAR*)(LPCTSTR)str, (int)m_bSaveResultByHour); |
| | | |
| | | // ly,2025.07.07 |
| | | str = GetFileString((void*)&m_bEnableAutoCopy); |
| | | if (str.IsEmpty() == TRUE) |
| | | return FALSE; |
| | |
| | | BOOL m_bUse_SaveDebugImage; |
| | | |
| | | public: |
| | | BOOL m_bSaveResultByHour; |
| | | |
| | | public: |
| | | BOOL m_bEnableAutoCopy; |
| | | CString m_strCopyToolExePath; |
| | | CString m_strCopyToolConfigPath; |
| | |
| | | DDX_Check(pDX,IDC_CHECK_USE_SAVE_DEBUG_IMAGE,m_pDlgHDSettingParm->m_bUse_SaveDebugImage); |
| | | DDX_Check(pDX, IDC_CHECK_USE_SAVE_ALL_DMP, g_bUse_SaveAllDMP); |
| | | |
| | | DDX_Check(pDX, IDC_CHECK_SAVE_RESULT_BY_HOUR, m_pDlgHDSettingParm->m_bSaveResultByHour); // ly,2025.07.10 |
| | | |
| | | DDX_Check(pDX, IDC_CHECK_ENABLE_AUTO_COPY, m_pDlgHDSettingParm->m_bEnableAutoCopy); // ly,2025.07.07 |
| | | DDX_Text(pDX, IDC_EDIT_COPY_TOOL_EXE_PATH, m_pDlgHDSettingParm->m_strCopyToolExePath); |
| | | DDX_Text(pDX, IDC_EDIT_COPY_TOOL_CONFIG_PATH, m_pDlgHDSettingParm->m_strCopyToolConfigPath); |