| | |
| | | MyLock.Unlock(); |
| | | return m_nDefect; |
| | | } |
| | | |
| | | int CDefectControl::ExtractDefect_RipThickness(DimensionDir emDim, int iCam, int iScan, const CDefect_Info& defectInfo, double dMeasured_um, double dSpecDiff_um) |
| | | { |
| | | if (m_pGrabber == NULL) { |
| | | return m_nDefect; |
| | | } |
| | | |
| | | CSingleLock MyLock(&m_csDefect); |
| | | MyLock.Lock(); |
| | | |
| | | if (m_nDefect >= m_maxDefect) { |
| | | MyLock.Unlock(); |
| | | return m_nDefect; |
| | | } |
| | | |
| | | CDefect* pDefect = GetDefect(m_nDefect); |
| | | if (pDefect == NULL) { |
| | | MyLock.Unlock(); |
| | | return m_nDefect; |
| | | } |
| | | |
| | | pDefect->Reset(); |
| | | pDefect->m_bJudge_NG = TRUE; // RIP 厚度异常即 NG |
| | | pDefect->m_nJudge_X_um = dMeasured_um; // 记录测得厚度 |
| | | pDefect->m_nJudge_Y_um = dSpecDiff_um; // 记录与规格差值 |
| | | pDefect->m_DefectInfo = defectInfo; |
| | | |
| | | int nXStart = defectInfo.m_ptDefectPos_pxl.x - (DEFECTIMAGE_WIDTH / 2); |
| | | int nYStart = defectInfo.m_ptDefectPos_pxl.y - (DEFECTIMAGE_HEIGHT / 2); |
| | | if (!m_pGrabber->GetSmallImage(iScan, pDefect->m_Image, nXStart, nYStart, DEFECTIMAGE_WIDTH, DEFECTIMAGE_HEIGHT, FALSE)) { |
| | | MyLock.Unlock(); |
| | | return m_nDefect; |
| | | } |
| | | |
| | | m_nDefect++; |
| | | |
| | | MyLock.Unlock(); |
| | | return m_nDefect; |
| | | } |
| | |
| | | |
| | | int ExtractDefect_Mark(DimensionDir emDim, int iCam, int iScan, CDefect_Info defect); |
| | | int ExtractDefect_CorChamfer(DimensionDir emDim, int iCam, int iScan, DefectLocation eDefect, CDefect_Info ptDefect, int nProfileIndex); //2024.6.12 |
| | | int ExtractDefect_RipThickness(DimensionDir emDim, int iCam, int iScan, const CDefect_Info& defectInfo, double dMeasured_um, double dSpecDiff_um); |
| | | void ResetDefectControl(); |
| | | int CheckDefectCount(); |
| | | int IncreaseDefectCount(){++m_nDefect; return m_nDefect;} |
| | |
| | | |
| | | DefectLoc_License, |
| | | |
| | | DefectLoc_Rip_Thickness_Glass, |
| | | DefectLoc_Rip_Thickness_Left, |
| | | DefectLoc_Rip_Thickness_Right, |
| | | |
| | | DefectLoc_Unknown, |
| | | |
| | | DefectLoc_None |
| | |
| | | _T("WS_Fail"), |
| | | |
| | | _T("Exception"), |
| | | |
| | | _T("License"), |
| | | |
| | | _T("Rip_GlassThickness"), |
| | | _T("Rip_LeftGap"), |
| | | _T("Rip_RightGap"), |
| | | |
| | | _T("Unknown") |
| | | }; |
| | | |
| | |
| | | eRcp_InsType_In_Burr, |
| | | eRcp_InsType_In_Chamfer, |
| | | eRcp_InsType_TopCorner, |
| | | eRcp_InsType_BotCorner |
| | | eRcp_InsType_BotCorner, |
| | | eRcp_InsType_RipThickness |
| | | }; |
| | | |
| | | static CString g_strInsType[10] = |
| | | static CString g_strInsType[] = |
| | | { |
| | | _T("Chip"), |
| | | _T("Crack"), |
| | |
| | | _T("In_Chamfer"), |
| | | _T("Top_Corner"), |
| | | _T("Bot_Corner"), |
| | | _T("Thickness") |
| | | }; |
| | | |
| | | enum eSideInsType |
| | |
| | | } |
| | | } |
| | | #endif // HALCON_VISION_KEY |
| | | |
| | | MeasureSideEdge_EI(eDim); |
| | | } |
| | | |
| | | BOOL CInspectCamera::MeasureSideEdge_EI(DimensionDir eDim) { |
| | | /* code */ |
| | | bool bExec = (DIMENSION_A_RIP == eDim) || (DIMENSION_B_RIP == eDim) || (DIMENSION_C_RIP == eDim) || (DIMENSION_D_RIP == eDim); |
| | | if (!bExec) return FALSE; |
| | | CSide_Data* pSideData = m_pGlassData->GetSideData(eDim); |
| | | |
| | | //查找边界 |
| | | CFrameBufferController* pFrameBufferController = m_pGrabber->GetFrameBuffer(); |
| | | int imgWidth = pFrameBufferController->GetFrameWidth(); |
| | | |
| | | //获取上边界和下边 |
| | | int nTopEdge = pSideData->m_nGlassStartLine; |
| | | int nBottomEdge = pSideData->m_nGlassEndLine; |
| | | g_pLog->DisplayMessage(_T("[APP]Measure Side Edge Start, StartEdge = %d, EndEdge = %d, Width = %d"), nTopEdge, nBottomEdge, imgWidth); |
| | | |
| | | stFrameIndex stFrame = m_pGrabber->GetGrabFrame(); |
| | | CRIP_THICKNESS_PARM& rip = m_pRecipe->m_SideParam[eDim].m_RipThk; |
| | | if (rip.m_bUseInspect != TRUE) { |
| | | return TRUE; |
| | | } |
| | | |
| | | int inspectNum = 36; |
| | | |
| | | //输入参数 |
| | | int topOffset = rip.m_nTopOffset; //T Offset |
| | | int botOffset = rip.m_nBottomOffset; //B Offset |
| | | int leftEdge = rip.m_nRectLeft; //Rect L |
| | | int rightEdge = rip.m_nRectRight; //Rect R |
| | | int leftThres = rip.m_nLeftThres; //Left Thres |
| | | int rightThres = rip.m_nRightThres; //Right Thres |
| | | int gassThres = rip.m_nGlassThres; //Gas Thres |
| | | |
| | | double dist_array[36]; //输出结果 |
| | | double left_dist_Gass_array[36]; //输出结果 |
| | | double right_dist_Gass_array[36]; //输出结果 |
| | | double xMinEdge_array_px[36]; //输出结果 |
| | | double yMinEdge_array_px[36]; //输出结果 |
| | | double xMaxEdge_array_px[36]; //输出结果 |
| | | double yMaxEdge_array_px[36]; //输出结果 |
| | | double xMinGas_array_px[36]; //输出结果 |
| | | double yMinGas_array_px[36]; //输出结果 |
| | | double xMaxGas_array_px[36]; //输出结果 |
| | | double yMaxGas_array_px[36]; //输出结果 |
| | | |
| | | int startY = nTopEdge + topOffset; |
| | | int endY = nBottomEdge - botOffset; |
| | | int step = (int)((endY - startY) / inspectNum); |
| | | g_pLog->DisplayMessage(_T("[APP]Measure Side Edge, (startY, endY, step) = (%d, %d, %d)"), startY, endY, step); |
| | | |
| | | for (int i = 0; i < inspectNum; i++) { |
| | | int x1 = leftEdge; |
| | | int y1 = startY + i * step; |
| | | int x2 = rightEdge; |
| | | int y2 = startY + (i + 1) * step; |
| | | |
| | | double szDist, leftGassDist, rightGassDist; |
| | | MeasureSideEdge_POS(eDim, |
| | | x1, y1, x2, y2, |
| | | leftThres, rightThres, gassThres, |
| | | xMinEdge_array_px[i], yMinEdge_array_px[i], xMaxEdge_array_px[i], yMaxEdge_array_px[i], |
| | | xMinGas_array_px[i], yMinGas_array_px[i], xMaxGas_array_px[i], yMaxGas_array_px[i], |
| | | szDist, leftGassDist, rightGassDist); |
| | | |
| | | dist_array[i] = m_dPixelSizeX * szDist; |
| | | left_dist_Gass_array[i] = m_dPixelSizeX * leftGassDist; |
| | | right_dist_Gass_array[i] = m_dPixelSizeX * rightGassDist; |
| | | |
| | | g_pLog->DisplayMessage(_T("[APP]Measure Result %d: LeftEdge = (%.1f, %.1f), LeftGas = (%.1f, %.1f), rightGas = (%.1f, %.1f), RightEdge = (%.1f, %.1f), (Dist, LeftGass, RightGass) = (%.1f, %.1f, %.1f)"), |
| | | i + 1, |
| | | xMinEdge_array_px[i], yMinEdge_array_px[i], |
| | | xMinGas_array_px[i], yMinGas_array_px[i], |
| | | xMaxGas_array_px[i], yMaxGas_array_px[i], |
| | | xMaxEdge_array_px[i], yMaxEdge_array_px[i], |
| | | dist_array[i], left_dist_Gass_array[i], right_dist_Gass_array[i]); |
| | | |
| | | // 添加缺陷 |
| | | int nStep = max(1, (endY - startY) / inspectNum); // 防 0 |
| | | auto SpecDiff = [](double v, double vMin, double vMax)->double { |
| | | if (v <= 0) return 0.0; // 无效值 |
| | | if (v < vMin) return v - vMin; // 负:低于下限 |
| | | if (v > vMax) return v - vMax; // 正:高于上限 |
| | | return 0.0; // 在规格内 |
| | | }; |
| | | |
| | | auto MakeBaseInfo = [&](CPoint pt, CRect rt, DefectLocation loc)->CDefect_Info { |
| | | CDefect_Info info; |
| | | info.m_iFrameIdx = stFrame.nFrameIdx; |
| | | info.m_nCamID = m_iCamera; |
| | | info.m_nScanIdx = stFrame.nScanIdx; |
| | | info.m_nGlassStartLine = pSideData->m_nGlassStartLine; |
| | | info.m_nSideIdx = (int)eDim; |
| | | info.m_ptDefectPos_pxl = pt; |
| | | info.m_rtDefectPos_pxl = rt; |
| | | info.m_DefectLoc = loc; |
| | | return info; |
| | | }; |
| | | |
| | | bool ngGlass = (dist_array[i] > 0) && (dist_array[i] < rip.m_nGlassSizeMin_um || dist_array[i] > rip.m_nGlassSizeMax_um); |
| | | bool ngLeft = (left_dist_Gass_array[i] > 0) && (left_dist_Gass_array[i] < rip.m_nLeftRipSizeMin_um || left_dist_Gass_array[i] > rip.m_nLeftRipSizeMax_um); |
| | | bool ngRight = (right_dist_Gass_array[i] > 0) && (right_dist_Gass_array[i] < rip.m_nRightRipSizeMin_um || right_dist_Gass_array[i] > rip.m_nRightRipSizeMax_um); |
| | | |
| | | // Glass 厚度 NG |
| | | if (ngGlass) { |
| | | CRect rt( |
| | | (int)min(min(xMinEdge_array_px[i], xMinGas_array_px[i]), min(xMaxEdge_array_px[i], xMaxGas_array_px[i])), |
| | | (int)min(min(yMinEdge_array_px[i], yMinGas_array_px[i]), min(yMaxEdge_array_px[i], yMaxGas_array_px[i])), |
| | | (int)max(max(xMinEdge_array_px[i], xMinGas_array_px[i]), max(xMaxEdge_array_px[i], xMaxGas_array_px[i])), |
| | | (int)max(max(yMinEdge_array_px[i], yMinGas_array_px[i]), max(yMaxEdge_array_px[i], yMaxGas_array_px[i])) |
| | | ); |
| | | CPoint pt((rt.left + rt.right) / 2, (rt.top + rt.bottom) / 2); |
| | | CDefect_Info defect = MakeBaseInfo(pt, rt, DefectLoc_Rip_Thickness_Glass); |
| | | double dDiff = SpecDiff(dist_array[i], rip.m_nGlassSizeMin_um, rip.m_nGlassSizeMax_um); |
| | | m_pDefectControl->ExtractDefect_RipThickness(eDim, m_iCamera, stFrame.nScanIdx, defect, dist_array[i], dDiff); |
| | | } |
| | | |
| | | // 左侧气隙 NG |
| | | if (ngLeft) { |
| | | CRect rt( |
| | | (int)min(xMinEdge_array_px[i], xMinGas_array_px[i]), |
| | | (int)min(yMinEdge_array_px[i], yMinGas_array_px[i]), |
| | | (int)max(xMinEdge_array_px[i], xMinGas_array_px[i]), |
| | | (int)max(yMinEdge_array_px[i], yMinGas_array_px[i]) |
| | | ); |
| | | CPoint pt((rt.left + rt.right) / 2, (rt.top + rt.bottom) / 2); |
| | | CDefect_Info defect = MakeBaseInfo(pt, rt, DefectLoc_Rip_Thickness_Left); |
| | | double dDiff = SpecDiff(left_dist_Gass_array[i], rip.m_nLeftRipSizeMin_um, rip.m_nLeftRipSizeMax_um); |
| | | m_pDefectControl->ExtractDefect_RipThickness(eDim, m_iCamera, stFrame.nScanIdx, defect, left_dist_Gass_array[i], dDiff); |
| | | } |
| | | |
| | | // 右侧气隙 NG |
| | | if (ngRight) { |
| | | CRect rt( |
| | | (int)min(xMaxEdge_array_px[i], xMaxGas_array_px[i]), |
| | | (int)min(yMaxEdge_array_px[i], yMaxGas_array_px[i]), |
| | | (int)max(xMaxEdge_array_px[i], xMaxGas_array_px[i]), |
| | | (int)max(yMaxEdge_array_px[i], yMaxGas_array_px[i]) |
| | | ); |
| | | CPoint pt((rt.left + rt.right) / 2, (rt.top + rt.bottom) / 2); |
| | | CDefect_Info defect = MakeBaseInfo(pt, rt, DefectLoc_Rip_Thickness_Right); |
| | | double dDiff = SpecDiff(right_dist_Gass_array[i], rip.m_nRightRipSizeMin_um, rip.m_nRightRipSizeMax_um); |
| | | m_pDefectControl->ExtractDefect_RipThickness(eDim, m_iCamera, stFrame.nScanIdx, defect, right_dist_Gass_array[i], dDiff); |
| | | } |
| | | } |
| | | |
| | | return TRUE; |
| | | } |
| | | |
| | | void CInspectCamera::MeasureSideEdge_POS(DimensionDir eDim, |
| | | int x1, int y1, int x2, int y2, |
| | | int leftThres, int rightThres, int gassThres, |
| | | double& minEdgeX, double& minEdgeY, double& maxEdgeX, double& maxEdgeY, |
| | | double& minGasX, double& minGasY, double& maxGasX, double& maxGasY, |
| | | double& szDist, double& leftGassDist, double& rightGassDist) { |
| | | /* code */ |
| | | szDist = 0.0f; |
| | | leftGassDist = 0.0f; |
| | | rightGassDist = 0.0f; |
| | | int width = x2 - x1 + 1; |
| | | int height = y2 - y1 + 1; |
| | | uchar* imgData = new uchar[width * height]; |
| | | try { |
| | | CutImageROI(imgData, eDim, x1, y1, x2, y2); |
| | | |
| | | MeasurePoint dotResult1[100]; |
| | | MeasurePoint dotResult2[100]; |
| | | MeasurePoint dotResult3[100]; |
| | | MeasurePoint dotResult4[100]; |
| | | MeasurePoint dotResult5[100]; |
| | | MeasurePoint dotResult6[100]; |
| | | MeasurePoint dotResult7[100]; |
| | | int dotNum1 = 0; |
| | | int dotNum2 = 0; |
| | | int dotNum3 = 0; |
| | | int dotNum4 = 0; |
| | | int dotNum5 = 0; |
| | | int dotNum6 = 0; |
| | | int dotNum7 = 0; |
| | | CVisionMeasureClass doExec; |
| | | double sigma = 2.5f; //输入参数, 增加参数 |
| | | doExec.doMeasurePosA(imgData, width, height, sigma, |
| | | dotResult1, dotNum1, |
| | | dotResult2, dotNum2, |
| | | dotResult3, dotNum3, |
| | | dotResult4, dotNum4, |
| | | dotResult5, dotNum5, |
| | | dotResult6, dotNum6, |
| | | dotResult7, dotNum7); |
| | | for (int i = 0; i < dotNum1; i++) { |
| | | dotResult1[i].x += x1; |
| | | dotResult1[i].y += y1; |
| | | } |
| | | for (int i = 0; i < dotNum2; i++) { |
| | | dotResult2[i].x += x1; |
| | | dotResult2[i].y += y1; |
| | | } |
| | | for (int i = 0; i < dotNum3; i++) { |
| | | dotResult3[i].x += x1; |
| | | dotResult3[i].y += y1; |
| | | } |
| | | for (int i = 0; i < dotNum4; i++) { |
| | | dotResult4[i].x += x1; |
| | | dotResult4[i].y += y1; |
| | | } |
| | | for (int i = 0; i < dotNum5; i++) { |
| | | dotResult5[i].x += x1; |
| | | dotResult5[i].y += y1; |
| | | } |
| | | for (int i = 0; i < dotNum6; i++) { |
| | | dotResult6[i].x += x1; |
| | | dotResult6[i].y += y1; |
| | | } |
| | | for (int i = 0; i < dotNum7; i++) { |
| | | dotResult7[i].x += x1; |
| | | dotResult7[i].y += y1; |
| | | } |
| | | |
| | | int fzDist = 4.5; //输入参数, 增加参数 |
| | | |
| | | double xMinResult[7] = { -1 }; |
| | | double yMinResult[7] = { -1 }; |
| | | double xMaxResult[7] = { -1 }; |
| | | double yMaxResult[7] = { -1 }; |
| | | double xMinGassResult[7] = { -1 }; |
| | | double yMinGassResult[7] = { -1 }; |
| | | double xMaxGassResult[7] = { -1 }; |
| | | double yMaxGassResult[7] = { -1 }; |
| | | |
| | | MeasureResultProc(dotResult1, dotNum1, leftThres, rightThres, gassThres, fzDist, |
| | | xMinResult[0], yMinResult[0], xMaxResult[0], yMaxResult[0], |
| | | xMinGassResult[0], yMinGassResult[0], xMaxGassResult[0], yMaxGassResult[0]); |
| | | MeasureResultProc(dotResult2, dotNum2, leftThres, rightThres, gassThres, fzDist, |
| | | xMinResult[1], yMinResult[1], xMaxResult[1], yMaxResult[1], |
| | | xMinGassResult[1], yMinGassResult[1], xMaxGassResult[1], yMaxGassResult[1]); |
| | | MeasureResultProc(dotResult3, dotNum3, leftThres, rightThres, gassThres, fzDist, |
| | | xMinResult[2], yMinResult[2], xMaxResult[2], yMaxResult[2], |
| | | xMinGassResult[2], yMinGassResult[2], xMaxGassResult[2], yMaxGassResult[2]); |
| | | MeasureResultProc(dotResult4, dotNum4, leftThres, rightThres, gassThres, fzDist, |
| | | xMinResult[3], yMinResult[3], xMaxResult[3], yMaxResult[3], |
| | | xMinGassResult[3], yMinGassResult[3], xMaxGassResult[3], yMaxGassResult[3]); |
| | | MeasureResultProc(dotResult5, dotNum5, leftThres, rightThres, gassThres, fzDist, |
| | | xMinResult[4], yMinResult[4], xMaxResult[4], yMaxResult[4], |
| | | xMinGassResult[4], yMinGassResult[4], xMaxGassResult[4], yMaxGassResult[4]); |
| | | MeasureResultProc(dotResult6, dotNum6, leftThres, rightThres, gassThres, fzDist, |
| | | xMinResult[5], yMinResult[5], xMaxResult[5], yMaxResult[5], |
| | | xMinGassResult[5], yMinGassResult[5], xMaxGassResult[5], yMaxGassResult[5]); |
| | | MeasureResultProc(dotResult7, dotNum7, leftThres, rightThres, gassThres, fzDist, |
| | | xMinResult[6], yMinResult[6], xMaxResult[6], yMaxResult[6], |
| | | xMinGassResult[6], yMinGassResult[6], xMaxGassResult[6], yMaxGassResult[6]); |
| | | |
| | | std::vector<double> vDist, vLeftGass, vRightGass; |
| | | for (int i = 0; i < 7; i++) { |
| | | if (xMinResult[i] > 0 && xMaxResult[i] > 0) { |
| | | double dx = xMaxResult[i] - xMinResult[i]; |
| | | double dy = yMaxResult[i] - yMinResult[i]; |
| | | double dist = sqrt(dx * dx + dy * dy); |
| | | vDist.push_back(dist); |
| | | } |
| | | if (xMinResult[i] > 0 && xMinGassResult[i] > 0) { |
| | | double dx = xMinGassResult[i] - xMinResult[i]; |
| | | double dy = yMinGassResult[i] - yMinResult[i]; |
| | | double dist = sqrt(dx * dx + dy * dy); |
| | | vLeftGass.push_back(dist); |
| | | } |
| | | if (xMaxResult[i] > 0 && xMaxGassResult[i] > 0) { |
| | | double dx = xMaxResult[i] - xMaxGassResult[i]; |
| | | double dy = yMaxResult[i] - yMaxGassResult[i]; |
| | | double dist = sqrt(dx * dx + dy * dy); |
| | | vRightGass.push_back(dist); |
| | | } |
| | | } |
| | | |
| | | double avgDist = 0.0f; |
| | | int sz = (int)(vDist.size()); |
| | | if (sz > 3){ |
| | | for (int i = 0; i < sz - 1; i++) { |
| | | for (int j = i + 1; j < sz; j++) { |
| | | if (vDist[i] > vDist[j]) { |
| | | double tmp = vDist[i]; |
| | | vDist[i] = vDist[j]; |
| | | vDist[j] = tmp; |
| | | } |
| | | } |
| | | } |
| | | double avg = 0.0f; |
| | | for (int i = 1; i < sz - 1; i++) { |
| | | avg += vDist[i]; |
| | | } |
| | | avgDist = avg / (sz - 2); |
| | | } |
| | | double avgLeftGass = 0.0f; |
| | | sz = (int)(vLeftGass.size()); |
| | | if (sz > 3) { |
| | | for (int i = 0; i < sz - 1; i++) { |
| | | for (int j = i + 1; j < sz; j++) { |
| | | if (vLeftGass[i] > vLeftGass[j]) { |
| | | double tmp = vLeftGass[i]; |
| | | vLeftGass[i] = vLeftGass[j]; |
| | | vLeftGass[j] = tmp; |
| | | } |
| | | } |
| | | } |
| | | double avg = 0.0f; |
| | | for (int i = 1; i < sz - 1; i++) { |
| | | avg += vLeftGass[i]; |
| | | } |
| | | avgLeftGass = avg / (sz - 2); |
| | | } |
| | | |
| | | double avgRightGass = 0.0f; |
| | | sz = (int)(vRightGass.size()); |
| | | if (sz > 3) { |
| | | for (int i = 0; i < sz - 1; i++) { |
| | | for (int j = i + 1; j < sz; j++) { |
| | | if (vRightGass[i] > vRightGass[j]) { |
| | | double tmp = vRightGass[i]; |
| | | vRightGass[i] = vRightGass[j]; |
| | | vRightGass[j] = tmp; |
| | | } |
| | | } |
| | | } |
| | | double avg = 0.0f; |
| | | for (int i = 1; i < sz - 1; i++) { |
| | | avg += vRightGass[i]; |
| | | } |
| | | avgRightGass = avg / (sz - 2); |
| | | } |
| | | |
| | | szDist = avgDist; |
| | | leftGassDist = avgLeftGass; |
| | | rightGassDist = avgRightGass; |
| | | |
| | | minEdgeX = xMinResult[3]; |
| | | minEdgeY = yMinResult[3]; |
| | | maxEdgeX = xMaxResult[3]; |
| | | maxEdgeY = yMaxResult[3]; |
| | | minGasX = minEdgeX + leftGassDist - 1; |
| | | minGasY = minEdgeY; |
| | | maxGasX = maxEdgeX - rightGassDist + 1; |
| | | maxGasY = maxEdgeY; |
| | | |
| | | delete[] imgData; |
| | | imgData = nullptr; |
| | | } |
| | | catch (...) { |
| | | delete[] imgData; |
| | | imgData = nullptr; |
| | | } |
| | | } |
| | | |
| | | bool CInspectCamera::MeasureResultProc(MeasurePoint* ptResult, int dotNum, int leftThres, int rightRes, int gasThres, double fzDist, |
| | | double& minX, double& minY, double& maxX, double& maxY, double& minGasX, double& minGasY, double& maxGasX, double& maxGasY){ |
| | | /* code */ |
| | | minX = -1.0f; |
| | | minY = -1.0f; |
| | | maxX = -1.0f; |
| | | maxY = -1.0f; |
| | | minGasX = -1.0f; |
| | | minGasY = -1.0f; |
| | | if (dotNum < 2) return false; |
| | | |
| | | //1. 首先查找minX, minY |
| | | bool bMinFin = false; |
| | | minX = MAXINT; |
| | | for (int i = 0; i < dotNum; i++) { |
| | | if (fabs(ptResult[i].cy) > leftThres && ptResult[i].x < minX) { |
| | | minX = ptResult[i].x; |
| | | minY = ptResult[i].y; |
| | | bMinFin = true; |
| | | } |
| | | } |
| | | if (!bMinFin) { |
| | | minX = -1.0f; |
| | | minY = -1.0f; |
| | | } |
| | | |
| | | //2. 查找左右点 |
| | | bool bMaxFind = false; |
| | | maxX = -1.0f; |
| | | for (int i = 0; i < dotNum; i++) { |
| | | if (fabs(ptResult[i].cy) > rightRes && ptResult[i].x > maxX) { |
| | | maxX = ptResult[i].x; |
| | | maxY = ptResult[i].y; |
| | | bMaxFind = true; |
| | | } |
| | | } |
| | | if (!bMaxFind) { |
| | | maxX = -1.0f; |
| | | maxY = -1.0f; |
| | | } |
| | | |
| | | //3. 查找最小气体点 |
| | | if (bMinFin) { |
| | | bool bFind = false; |
| | | minGasX = MAXINT; |
| | | for (int i = 0; i < dotNum; i++) { |
| | | double dx = ptResult[i].x - minX; |
| | | double dy = ptResult[i].y - minY; |
| | | double dist = sqrt(dx * dx + dy * dy); |
| | | if (dist > fzDist) { |
| | | if (fabs(ptResult[i].cy) > gasThres && ptResult[i].x < minGasX && ptResult[i].x > minX) { |
| | | minGasX = ptResult[i].x; |
| | | minGasY = ptResult[i].y; |
| | | bFind = true; |
| | | } |
| | | } |
| | | } |
| | | if (!bFind) { |
| | | minGasX = -1.0f; |
| | | minGasY = -1.0f; |
| | | } |
| | | } |
| | | |
| | | //4. 查找最大气体点 |
| | | if (bMaxFind) { |
| | | bool bFind = false; |
| | | maxGasX = -1.0f; |
| | | for (int i = 0; i < dotNum; i++) { |
| | | double dx = ptResult[i].x - maxX; |
| | | double dy = ptResult[i].y - maxY; |
| | | double dist = sqrt(dx * dx + dy * dy); |
| | | if (dist > fzDist) { |
| | | if (fabs(ptResult[i].cy) > gasThres && ptResult[i].x > maxGasX && ptResult[i].x < maxX) { |
| | | maxGasX = ptResult[i].x; |
| | | maxGasY = ptResult[i].y; |
| | | bFind = true; |
| | | } |
| | | } |
| | | } |
| | | if (!bFind) { |
| | | maxGasX = -1.0f; |
| | | maxGasY = -1.0f; |
| | | } |
| | | } |
| | | |
| | | return true; |
| | | } |
| | | |
| | | int CInspectCamera::CutImageROI(uchar* img, DimensionDir eDim, int x1, int y1, int x2, int y2) { |
| | | /* code */ |
| | | int iScan = m_pHardparm->GetScanToDimension(eDim); |
| | | |
| | | int width = x2 - x1 + 1; |
| | | for (int i = y1; i <= y2; i++) { |
| | | LPBYTE lp = m_pGrabber->GetFrameHeaderLine(iScan, i); |
| | | std::memcpy(img+ (i-y1) * width, lp+x1, width); |
| | | } |
| | | |
| | | return 1; |
| | | } |
| | | |
| | | BOOL CInspectCamera::CheckThreadEnd(int iThread, stFrameIndex stFrame) |
| | |
| | | // 1. Find End Line.. (Corner를 제외한 Side라인을 찾기 위해 End Line부터 찾는다) |
| | | FindEndLine(iThread, emDim, stFrame); |
| | | |
| | | bool bIsRipSide = (emDim == DIMENSION_A_RIP || emDim == DIMENSION_B_RIP || emDim == DIMENSION_C_RIP || emDim == DIMENSION_D_RIP); |
| | | if (bIsRipSide) { |
| | | return TRUE; |
| | | } |
| | | |
| | | // 2. Find Side Line.. (해당 프레임에서 Corner/Notch 를 제외한 Side 라인 찾기) |
| | | #if USE_AI_DETECT |
| | | FindSideLine(iThread, emDim, stFrame); |
| | |
| | | |
| | | //13. 视觉功能 |
| | | void FinallyVisionProc(DimensionDir eDim); |
| | | |
| | | //14. 截图图像 |
| | | int CutImageROI(uchar* img, DimensionDir eDim, int x1, int y1, int x2, int y2); |
| | | BOOL MeasureSideEdge_EI(DimensionDir eDim); |
| | | void MeasureSideEdge_POS(DimensionDir eDim, |
| | | int x1, int y1, int x2, int y2, |
| | | int leftThres, int rightThres, int gassThres, |
| | | double& minEdgeX, double& minEdgeY, double& maxEdgeX, double& maxEdgeY, |
| | | double& minGasX, double& minGasY, double& maxGasX, double& maxGasY, |
| | | double& szDist, double& leftGassDist, double& rightGassDist); |
| | | bool MeasureResultProc(MeasurePoint* ptResult, int dotNum, int leftThres, int rightRes, int gasThres, double fzDist, |
| | | double& minX, double& minY, double& maxX, double& maxY, double& minGasX, double& minGasY, double& maxGasX, double& maxGasY); |
| | | |
| | | protected: |
| | | void SaveFullImageCopy(int iScan); |
| | |
| | | m_nUserDefectAreaCount = 0; |
| | | for(int i=0; i<MAX_SIDE_USER_DEFECT_AREA_COUNT; i++) |
| | | m_UserDefectPrm[i].Reset(); |
| | | |
| | | m_RipThk.Reset(); |
| | | } |
| | | |
| | | BOOL CSIDE_PARM::ReadRecipe(CConfig *pFile, int nSideIdx) |
| | |
| | | for(int nUserDefectAreaIdx=0; nUserDefectAreaIdx<m_nUserDefectAreaCount; nUserDefectAreaIdx++) |
| | | m_UserDefectPrm[nUserDefectAreaIdx].ReadRecipe(pFile, nSideIdx, nUserDefectAreaIdx); |
| | | |
| | | m_RipThk.ReadRecipe(pFile, nSideIdx); |
| | | |
| | | return TRUE; |
| | | } |
| | | |
| | |
| | | |
| | | for(int nUserDefectAreaIdx=0; nUserDefectAreaIdx<m_nUserDefectAreaCount; nUserDefectAreaIdx++) |
| | | m_UserDefectPrm[nUserDefectAreaIdx].WriteRecipe(pFile, nSideIdx, nUserDefectAreaIdx); |
| | | |
| | | m_RipThk.WriteRecipe(pFile, nSideIdx); |
| | | |
| | | return TRUE; |
| | | } |
| | |
| | | |
| | | return TRUE; |
| | | } |
| | | |
| | | void CRIP_THICKNESS_PARM::Reset() |
| | | { |
| | | m_bUseInspect = FALSE; |
| | | m_nLeftThres = m_nRightThres = m_nGlassThres = 0; |
| | | m_nRipDir = 0; |
| | | m_nRectLeft = m_nRectRight = 0; |
| | | m_nTopOffset = m_nBottomOffset = 0; |
| | | |
| | | m_nGlassSizeMin_um = 0; m_nGlassSizeMax_um = 0; |
| | | m_nLeftRipSizeMin_um = 0; m_nLeftRipSizeMax_um = 0; |
| | | m_nRightRipSizeMin_um = 0; m_nRightRipSizeMax_um = 0; |
| | | } |
| | | |
| | | BOOL CRIP_THICKNESS_PARM::ReadRecipe(CConfig* pFile, int nSideIdx) |
| | | { |
| | | if (!pFile) { |
| | | return FALSE; |
| | | } |
| | | |
| | | if (nSideIdx < 0 || nSideIdx >= MAX_SIDE_COUNT) { |
| | | return FALSE; |
| | | } |
| | | |
| | | CString k; |
| | | k = _T("RipThk_m_bUseInspect"); |
| | | pFile->GetItemValue(nSideIdx, k, m_bUseInspect, 0); |
| | | k = _T("RipThk_m_nLeftThres"); |
| | | pFile->GetItemValue(nSideIdx, k, m_nLeftThres, 0); |
| | | k = _T("RipThk_m_nRightThres"); |
| | | pFile->GetItemValue(nSideIdx, k, m_nRightThres, 0); |
| | | k = _T("RipThk_m_nGlassThres"); |
| | | pFile->GetItemValue(nSideIdx, k, m_nGlassThres, 0); |
| | | k = _T("RipThk_m_nRipDir"); |
| | | pFile->GetItemValue(nSideIdx, k, m_nRipDir, 2); |
| | | k = _T("RipThk_m_nRectLeft"); |
| | | pFile->GetItemValue(nSideIdx, k, m_nRectLeft, 0); |
| | | k = _T("RipThk_m_nTopOffset"); |
| | | pFile->GetItemValue(nSideIdx, k, m_nTopOffset, 0); |
| | | k = _T("RipThk_m_nRectRight"); |
| | | pFile->GetItemValue(nSideIdx, k, m_nRectRight, 0); |
| | | k = _T("RipThk_m_nBottomOffset"); |
| | | pFile->GetItemValue(nSideIdx, k, m_nBottomOffset, 0); |
| | | k = _T("RipThk_m_nGlassSizeMin_um"); |
| | | pFile->GetItemValue(nSideIdx, k, m_nGlassSizeMin_um, 0); |
| | | k = _T("RipThk_m_nGlassSizeMax_um"); |
| | | pFile->GetItemValue(nSideIdx, k, m_nGlassSizeMax_um, 0); |
| | | k = _T("RipThk_m_nLeftRipSizeMin_um"); |
| | | pFile->GetItemValue(nSideIdx, k, m_nLeftRipSizeMin_um, 0); |
| | | k = _T("RipThk_m_nLeftRipSizeMax_um"); |
| | | pFile->GetItemValue(nSideIdx, k, m_nLeftRipSizeMax_um, 0); |
| | | k = _T("RipThk_m_nRightRipSizeMin_um"); |
| | | pFile->GetItemValue(nSideIdx, k, m_nRightRipSizeMin_um, 0); |
| | | k = _T("RipThk_m_nRightRipSizeMax_um"); |
| | | pFile->GetItemValue(nSideIdx, k, m_nRightRipSizeMax_um, 0); |
| | | |
| | | return TRUE; |
| | | } |
| | | |
| | | BOOL CRIP_THICKNESS_PARM::WriteRecipe(CConfig* pFile, int nSideIdx) |
| | | { |
| | | if (!pFile) { |
| | | return FALSE; |
| | | } |
| | | |
| | | if (nSideIdx < 0 || nSideIdx >= MAX_SIDE_COUNT) { |
| | | return FALSE; |
| | | } |
| | | |
| | | CString k; |
| | | k = _T("RipThk_m_bUseInspect"); |
| | | pFile->SetItemValue(nSideIdx, k, m_bUseInspect); |
| | | k = _T("RipThk_m_nLeftThres"); |
| | | pFile->SetItemValue(nSideIdx, k, m_nLeftThres); |
| | | k = _T("RipThk_m_nRightThres"); |
| | | pFile->SetItemValue(nSideIdx, k, m_nRightThres); |
| | | k = _T("RipThk_m_nGlassThres"); |
| | | pFile->SetItemValue(nSideIdx, k, m_nGlassThres); |
| | | k = _T("RipThk_m_nRipDir"); |
| | | pFile->SetItemValue(nSideIdx, k, m_nRipDir); |
| | | k = _T("RipThk_m_nRectLeft"); |
| | | pFile->SetItemValue(nSideIdx, k, m_nRectLeft); |
| | | k = _T("RipThk_m_nTopOffset"); |
| | | pFile->SetItemValue(nSideIdx, k, m_nTopOffset); |
| | | k = _T("RipThk_m_nRectRight"); |
| | | pFile->SetItemValue(nSideIdx, k, m_nRectRight); |
| | | k = _T("RipThk_m_nBottomOffset"); |
| | | pFile->SetItemValue(nSideIdx, k, m_nBottomOffset); |
| | | k = _T("RipThk_m_nGlassSizeMin_um"); |
| | | pFile->SetItemValue(nSideIdx, k, m_nGlassSizeMin_um); |
| | | k = _T("RipThk_m_nGlassSizeMax_um"); |
| | | pFile->SetItemValue(nSideIdx, k, m_nGlassSizeMax_um); |
| | | k = _T("RipThk_m_nLeftRipSizeMin_um"); |
| | | pFile->SetItemValue(nSideIdx, k, m_nLeftRipSizeMin_um); |
| | | k = _T("RipThk_m_nLeftRipSizeMax_um"); |
| | | pFile->SetItemValue(nSideIdx, k, m_nLeftRipSizeMax_um); |
| | | k = _T("RipThk_m_nRightRipSizeMin_um"); |
| | | pFile->SetItemValue(nSideIdx, k, m_nRightRipSizeMin_um); |
| | | k = _T("RipThk_m_nRightRipSizeMax_um"); |
| | | pFile->SetItemValue(nSideIdx, k, m_nRightRipSizeMax_um); |
| | | |
| | | return TRUE; |
| | | } |
| | |
| | | int m_nJudge_Size_Min_OR_AND; // 0 : No Use, 1 : OR, 2 : AND |
| | | }; |
| | | |
| | | // RIP Thickness |
| | | struct CRIP_THICKNESS_PARM |
| | | { |
| | | // Inspect |
| | | BOOL m_bUseInspect = FALSE; |
| | | int m_nLeftThres = 0; |
| | | int m_nRightThres = 0; |
| | | int m_nGlassThres = 0; |
| | | int m_nRipDir = 0; // 0:L 1:R 2:L+R |
| | | int m_nRectLeft = 0; // Inspect Rect L |
| | | int m_nTopOffset = 0; // Inspect Top Offset |
| | | int m_nRectRight = 0; // Inspect Rect R |
| | | int m_nBottomOffset = 0; // Inspect Bottom Offset |
| | | |
| | | // Judgement |
| | | int m_nGlassSizeMin_um = 0; |
| | | int m_nGlassSizeMax_um = 0; |
| | | int m_nLeftRipSizeMin_um = 0; |
| | | int m_nLeftRipSizeMax_um = 0; |
| | | int m_nRightRipSizeMin_um = 0; |
| | | int m_nRightRipSizeMax_um = 0; |
| | | |
| | | void Reset(); |
| | | BOOL ReadRecipe(CConfig* pFile, int nSideIdx); |
| | | BOOL WriteRecipe(CConfig* pFile, int nSideIdx); |
| | | }; |
| | | |
| | | class CSIDE_PARM |
| | | { |
| | | public: |
| | |
| | | // User Defect |
| | | int m_nUserDefectAreaCount; |
| | | CUSER_DEFECT_AREA_PARM m_UserDefectPrm[MAX_SIDE_USER_DEFECT_AREA_COUNT]; |
| | | |
| | | // Rip Thickness |
| | | CRIP_THICKNESS_PARM m_RipThk; |
| | | }; |
| | | |
| | | class CGlassRecipe |
| | |
| | | BOOL CViewMain_ScanImage::ManualThreadStart(int nCmd,int nIndex /*= -1*/) |
| | | { |
| | | if(m_pManualProcess) { |
| | | DWORD dwWait = ::WaitForSingleObject(m_pManualProcess->m_hThread, 1000); |
| | | DWORD dwWait = ::WaitForSingleObject(m_pManualProcess->m_hThread, 3000); |
| | | if (dwWait == WAIT_TIMEOUT) { |
| | | DWORD dwExitCode; |
| | | if ((::GetExitCodeThread(m_pManualProcess->m_hThread, &dwExitCode)) && (dwExitCode == STILL_ACTIVE)) { |
| | |
| | | ON_EVENT(CViewMain_Recipe, IDC_RDO_INSTYPE_IN_CHAMFER, DISPID_CLICK, CViewMain_Recipe::ClickRdoInsType, VTS_NONE) |
| | | ON_EVENT(CViewMain_Recipe, IDC_RDO_INSTYPE_TOP_CORNER, DISPID_CLICK, CViewMain_Recipe::ClickRdoInsType, VTS_NONE) |
| | | ON_EVENT(CViewMain_Recipe, IDC_RDO_INSTYPE_BOT_CORNER, DISPID_CLICK, CViewMain_Recipe::ClickRdoInsType, VTS_NONE) |
| | | ON_EVENT(CViewMain_Recipe, IDC_RDO_INSTYPE_RIP_THICKNESS, DISPID_CLICK, CViewMain_Recipe::ClickRdoInsType, VTS_NONE) |
| | | |
| | | ON_EVENT(CViewMain_Recipe, IDC_BTN_TOP_MARK_UPDATE_0, DISPID_CLICK, CViewMain_Recipe::ClickBtnMarkUpdate, VTS_NONE) |
| | | ON_EVENT(CViewMain_Recipe, IDC_BTN_TOP_MARK_UPDATE_1, DISPID_CLICK, CViewMain_Recipe::ClickBtnMarkUpdate, VTS_NONE) |
| | |
| | | break; |
| | | case IDC_RDO_INSTYPE_BOT_CORNER: eSelInsType = eRcp_InsType_BotCorner; |
| | | break; |
| | | case IDC_RDO_INSTYPE_RIP_THICKNESS: eSelInsType = eRcp_InsType_RipThickness; |
| | | break; |
| | | default: |
| | | return; |
| | | } |
| | | |
| | | if(m_eSelectInsType == eSelInsType) |
| | | // Check Ins Type |
| | | if (m_eSelectInsType == eSelInsType) { |
| | | return; |
| | | } |
| | | |
| | | // Change Ins Type |
| | | m_eSelectInsType = eSelInsType; |
| | | |
| | | // Update UI |
| | | Init_SideInsInfo(); |
| | | Fill_SideInsInfo(FALSE); |
| | | |
| | |
| | | case eRcp_InsType_BotCorner : |
| | | nRows = 14; |
| | | break; |
| | | case eRcp_InsType_RipThickness: |
| | | nRows = 10; |
| | | break; |
| | | default: |
| | | break; |
| | | } |
| | |
| | | m_SideInspectInfo.SetItemText(nRowIdx++, nColIdx, vecParams[i]); |
| | | } |
| | | } |
| | | else if (m_eSelectInsType == eRcp_InsType_RipThickness) { |
| | | std::vector<CString> vecParams; |
| | | strTemp.Format(_T("%s Use (0:OFF/1:ON)"), g_strInsType[m_eSelectInsType]); |
| | | vecParams.push_back(strTemp); |
| | | strTemp.Format(_T("%s Ins. Left Thres"), g_strInsType[m_eSelectInsType]); |
| | | vecParams.push_back(strTemp); |
| | | strTemp.Format(_T("%s Ins. Right Thres"), g_strInsType[m_eSelectInsType]); |
| | | vecParams.push_back(strTemp); |
| | | strTemp.Format(_T("%s Glsss Thres"), g_strInsType[m_eSelectInsType]); |
| | | vecParams.push_back(strTemp); |
| | | strTemp.Format(_T("%s Rip Dir. (0:Left/1:Right/2:Both)"), g_strInsType[m_eSelectInsType]); |
| | | vecParams.push_back(strTemp); |
| | | strTemp.Format(_T("%s Ins. Rect L"), g_strInsType[m_eSelectInsType]); |
| | | vecParams.push_back(strTemp); |
| | | strTemp.Format(_T("%s Ins. T Offset"), g_strInsType[m_eSelectInsType]); |
| | | vecParams.push_back(strTemp); |
| | | strTemp.Format(_T("%s Ins. Rect R"), g_strInsType[m_eSelectInsType]); |
| | | vecParams.push_back(strTemp); |
| | | strTemp.Format(_T("%s Ins. B Offset"), g_strInsType[m_eSelectInsType]); |
| | | vecParams.push_back(strTemp); |
| | | |
| | | CLanguageControl* pLanguageControl = g_pStatus->m_pLanguageControl; |
| | | |
| | | if (pLanguageControl != NULL) { |
| | | for (int i = 0; i < vecParams.size(); i++) { |
| | | CString strParam = pLanguageControl->GetString(m_eSelectLangType, vecParams[i]); |
| | | |
| | | if (strParam.IsEmpty() || strParam.GetLength() == 0) { |
| | | continue; |
| | | } |
| | | |
| | | vecParams[i] = strParam; |
| | | } |
| | | } |
| | | |
| | | for (int i = 0; i < vecParams.size(); i++) { |
| | | m_SideInspectInfo.GetCell(nRowIdx, nColIdx)->SetState(GVIS_READONLY); |
| | | m_SideInspectInfo.SetRowHeight(nRowIdx, 19); |
| | | m_SideInspectInfo.SetItemText(nRowIdx++, nColIdx, vecParams[i]); |
| | | } |
| | | } |
| | | |
| | | m_SideInspectInfo.SetFixedRowSelection(FALSE); |
| | | m_SideInspectInfo.SetFixedColumnSelection(FALSE); |
| | |
| | | case eRcp_InsType_TopCorner : |
| | | case eRcp_InsType_BotCorner : |
| | | nRows = 11; |
| | | break; |
| | | case eRcp_InsType_RipThickness: |
| | | nRows = 7; |
| | | break; |
| | | default: |
| | | break; |
| | |
| | | |
| | | for(int i=0; i<vecParams.size(); i++) |
| | | { |
| | | m_JudgementInfo.GetCell(nRowIdx, nColIdx)->SetState(GVIS_READONLY); |
| | | m_JudgementInfo.SetRowHeight(nRowIdx, 19); |
| | | m_JudgementInfo.SetItemText(nRowIdx++, nColIdx, vecParams[i]); |
| | | } |
| | | } |
| | | else if (eRcp_InsType_RipThickness == m_eSelectInsType) { |
| | | std::vector<CString> vecParams; |
| | | strTemp.Format(_T("Glass Size Min um"), g_strInsType[m_eSelectInsType]); |
| | | vecParams.push_back(strTemp); |
| | | strTemp.Format(_T("Glass Size Max um"), g_strInsType[m_eSelectInsType]); |
| | | vecParams.push_back(strTemp); |
| | | strTemp.Format(_T("Left Rip Size Min um"), g_strInsType[m_eSelectInsType]); |
| | | vecParams.push_back(strTemp); |
| | | strTemp.Format(_T("Left Rip Size Max um"), g_strInsType[m_eSelectInsType]); |
| | | vecParams.push_back(strTemp); |
| | | strTemp.Format(_T("Right Rip Size Min um"), g_strInsType[m_eSelectInsType]); |
| | | vecParams.push_back(strTemp); |
| | | strTemp.Format(_T("Right Rip Size Max um"), g_strInsType[m_eSelectInsType]); |
| | | vecParams.push_back(strTemp); |
| | | |
| | | CLanguageControl* pLanguageControl = g_pStatus->m_pLanguageControl; |
| | | |
| | | if (pLanguageControl != NULL) { |
| | | for (int i = 0; i < vecParams.size(); i++) { |
| | | CString strParam = pLanguageControl->GetString(m_eSelectLangType, vecParams[i]); |
| | | |
| | | if (strParam.IsEmpty() || strParam.GetLength() == 0) |
| | | continue; |
| | | |
| | | vecParams[i] = strParam; |
| | | } |
| | | } |
| | | |
| | | for (int i = 0; i < vecParams.size(); i++) { |
| | | m_JudgementInfo.GetCell(nRowIdx, nColIdx)->SetState(GVIS_READONLY); |
| | | m_JudgementInfo.SetRowHeight(nRowIdx, 19); |
| | | m_JudgementInfo.SetItemText(nRowIdx++, nColIdx, vecParams[i]); |
| | |
| | | strTemp.Format(_T("%d"), pSideParam->m_nBottomCornerEdgeThreshold ); |
| | | m_SideInspectInfo.SetItemText(nRowIdx++, nColIdx, strTemp); |
| | | } |
| | | else if (m_eSelectInsType == eRcp_InsType_RipThickness) |
| | | { |
| | | CRIP_THICKNESS_PARM& rip = pSideParam->m_RipThk; |
| | | // 1. Use (0/1) |
| | | if (rip.m_bUseInspect) m_SideInspectInfo.GetCell(nRowIdx, nColIdx)->SetBackClr(RGB(50, 255, 50)); |
| | | else m_SideInspectInfo.GetCell(nRowIdx, nColIdx)->SetBackClr(RGB(255, 50, 50)); |
| | | strTemp.Format(_T("%d"), rip.m_bUseInspect); |
| | | m_SideInspectInfo.SetItemText(nRowIdx++, nColIdx, strTemp); |
| | | |
| | | // 2. Left Thres |
| | | m_SideInspectInfo.GetCell(nRowIdx, nColIdx)->SetBackClr(uCellColor); |
| | | strTemp.Format(_T("%d"), rip.m_nLeftThres); |
| | | m_SideInspectInfo.SetItemText(nRowIdx++, nColIdx, strTemp); |
| | | |
| | | // 3. Right Thres |
| | | m_SideInspectInfo.GetCell(nRowIdx, nColIdx)->SetBackClr(uCellColor); |
| | | strTemp.Format(_T("%d"), rip.m_nRightThres); |
| | | m_SideInspectInfo.SetItemText(nRowIdx++, nColIdx, strTemp); |
| | | |
| | | // 4. Glass Thres |
| | | m_SideInspectInfo.GetCell(nRowIdx, nColIdx)->SetBackClr(uCellColor); |
| | | strTemp.Format(_T("%d"), rip.m_nGlassThres); |
| | | m_SideInspectInfo.SetItemText(nRowIdx++, nColIdx, strTemp); |
| | | |
| | | // 5. Rip Direction (0/1/2) |
| | | m_SideInspectInfo.GetCell(nRowIdx, nColIdx)->SetBackClr(uCellColor); |
| | | strTemp.Format(_T("%d"), rip.m_nRipDir); |
| | | m_SideInspectInfo.SetItemText(nRowIdx++, nColIdx, strTemp); |
| | | |
| | | // 6. Rect L |
| | | m_SideInspectInfo.GetCell(nRowIdx, nColIdx)->SetBackClr(uCellColor); |
| | | strTemp.Format(_T("%d"), rip.m_nRectLeft); |
| | | m_SideInspectInfo.SetItemText(nRowIdx++, nColIdx, strTemp); |
| | | |
| | | // 7. T Offset |
| | | m_SideInspectInfo.GetCell(nRowIdx, nColIdx)->SetBackClr(uCellColor); |
| | | strTemp.Format(_T("%d"), rip.m_nTopOffset); |
| | | m_SideInspectInfo.SetItemText(nRowIdx++, nColIdx, strTemp); |
| | | |
| | | // 8. Rect R |
| | | m_SideInspectInfo.GetCell(nRowIdx, nColIdx)->SetBackClr(uCellColor); |
| | | strTemp.Format(_T("%d"), rip.m_nRectRight); |
| | | m_SideInspectInfo.SetItemText(nRowIdx++, nColIdx, strTemp); |
| | | |
| | | // 9. B Offset |
| | | m_SideInspectInfo.GetCell(nRowIdx, nColIdx)->SetBackClr(uCellColor); |
| | | strTemp.Format(_T("%d"), rip.m_nBottomOffset); |
| | | m_SideInspectInfo.SetItemText(nRowIdx++, nColIdx, strTemp); |
| | | } |
| | | } |
| | | |
| | | m_SideInspectInfo.Invalidate(); |
| | |
| | | strTemp = m_SideInspectInfo.GetItemText(nRowIdx++, nColIdx); |
| | | pSideParam->m_nBottomCornerEdgeThreshold = _wtoi(strTemp); |
| | | } |
| | | else if (m_eSelectInsType == eRcp_InsType_RipThickness) |
| | | { |
| | | CRIP_THICKNESS_PARM& rip = pSideParam->m_RipThk; |
| | | |
| | | // 1. Use |
| | | strTemp = m_SideInspectInfo.GetItemText(nRowIdx++, nColIdx); |
| | | rip.m_bUseInspect = _wtoi(strTemp); |
| | | |
| | | // 2. Left Thres |
| | | strTemp = m_SideInspectInfo.GetItemText(nRowIdx++, nColIdx); |
| | | rip.m_nLeftThres = _wtoi(strTemp); |
| | | |
| | | // 3. Right Thres |
| | | strTemp = m_SideInspectInfo.GetItemText(nRowIdx++, nColIdx); |
| | | rip.m_nRightThres = _wtoi(strTemp); |
| | | |
| | | // 4. Glass Thres |
| | | strTemp = m_SideInspectInfo.GetItemText(nRowIdx++, nColIdx); |
| | | rip.m_nGlassThres = _wtoi(strTemp); |
| | | |
| | | // 5. Rip Direction |
| | | strTemp = m_SideInspectInfo.GetItemText(nRowIdx++, nColIdx); |
| | | rip.m_nRipDir = _wtoi(strTemp); |
| | | |
| | | // 6. Rect L |
| | | strTemp = m_SideInspectInfo.GetItemText(nRowIdx++, nColIdx); |
| | | rip.m_nRectLeft = _wtoi(strTemp); |
| | | |
| | | // 7. T Offset |
| | | strTemp = m_SideInspectInfo.GetItemText(nRowIdx++, nColIdx); |
| | | rip.m_nTopOffset = _wtoi(strTemp); |
| | | |
| | | // 8. Rect R |
| | | strTemp = m_SideInspectInfo.GetItemText(nRowIdx++, nColIdx); |
| | | rip.m_nRectRight = _wtoi(strTemp); |
| | | |
| | | // 9. B Offset |
| | | strTemp = m_SideInspectInfo.GetItemText(nRowIdx++, nColIdx); |
| | | rip.m_nBottomOffset = _wtoi(strTemp); |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | |
| | | void CViewMain_Recipe::Fill_JudgementInfo(BOOL bGetData) |
| | | { |
| | |
| | | strTemp.Format(_T("%d"), pSideParam->m_nBottomCorner_Measure_Judge_OR_AND ); |
| | | m_JudgementInfo.SetItemText(nRowIdx++, nColIdx, strTemp); |
| | | } |
| | | else if (m_eSelectInsType == eRcp_InsType_RipThickness) |
| | | { |
| | | const CRIP_THICKNESS_PARM& rip = pSideParam->m_RipThk; |
| | | |
| | | // 1. Glass Size Min um |
| | | m_JudgementInfo.GetCell(nRowIdx, nColIdx)->SetBackClr(uCellColor); |
| | | strTemp.Format(_T("%d"), rip.m_nGlassSizeMin_um); |
| | | m_JudgementInfo.SetItemText(nRowIdx++, nColIdx, strTemp); |
| | | |
| | | // 2. Glass Size Max um |
| | | m_JudgementInfo.GetCell(nRowIdx, nColIdx)->SetBackClr(uCellColor); |
| | | strTemp.Format(_T("%d"), rip.m_nGlassSizeMax_um); |
| | | m_JudgementInfo.SetItemText(nRowIdx++, nColIdx, strTemp); |
| | | |
| | | // 3. Left Rip Size Min um |
| | | m_JudgementInfo.GetCell(nRowIdx, nColIdx)->SetBackClr(uCellColor); |
| | | strTemp.Format(_T("%d"), rip.m_nLeftRipSizeMin_um); |
| | | m_JudgementInfo.SetItemText(nRowIdx++, nColIdx, strTemp); |
| | | |
| | | // 4. Left Rip Size Max um |
| | | m_JudgementInfo.GetCell(nRowIdx, nColIdx)->SetBackClr(uCellColor); |
| | | strTemp.Format(_T("%d"), rip.m_nLeftRipSizeMax_um); |
| | | m_JudgementInfo.SetItemText(nRowIdx++, nColIdx, strTemp); |
| | | |
| | | // 5. Right Rip Size Min um |
| | | m_JudgementInfo.GetCell(nRowIdx, nColIdx)->SetBackClr(uCellColor); |
| | | strTemp.Format(_T("%d"), rip.m_nRightRipSizeMin_um); |
| | | m_JudgementInfo.SetItemText(nRowIdx++, nColIdx, strTemp); |
| | | |
| | | // 6. Right Rip Size Max um |
| | | m_JudgementInfo.GetCell(nRowIdx, nColIdx)->SetBackClr(uCellColor); |
| | | strTemp.Format(_T("%d"), rip.m_nRightRipSizeMax_um); |
| | | m_JudgementInfo.SetItemText(nRowIdx++, nColIdx, strTemp); |
| | | } |
| | | } |
| | | |
| | | m_JudgementInfo.Invalidate(); |
| | |
| | | strTemp = m_JudgementInfo.GetItemText(nRowIdx++, nColIdx); |
| | | pSideParam->m_nBottomCorner_Measure_Judge_OR_AND = _wtoi(strTemp); |
| | | } |
| | | else if (m_eSelectInsType == eRcp_InsType_RipThickness) |
| | | { |
| | | CRIP_THICKNESS_PARM& rip = pSideParam->m_RipThk; |
| | | |
| | | // 1. Glass Size Min um |
| | | strTemp = m_JudgementInfo.GetItemText(nRowIdx++, nColIdx); |
| | | rip.m_nGlassSizeMin_um = _wtoi(strTemp); |
| | | |
| | | // 2. Glass Size Max um |
| | | strTemp = m_JudgementInfo.GetItemText(nRowIdx++, nColIdx); |
| | | rip.m_nGlassSizeMax_um = _wtoi(strTemp); |
| | | |
| | | // 3. Left Rip Size Min um |
| | | strTemp = m_JudgementInfo.GetItemText(nRowIdx++, nColIdx); |
| | | rip.m_nLeftRipSizeMin_um = _wtoi(strTemp); |
| | | |
| | | // 4. Left Rip Size Max um |
| | | strTemp = m_JudgementInfo.GetItemText(nRowIdx++, nColIdx); |
| | | rip.m_nLeftRipSizeMax_um = _wtoi(strTemp); |
| | | |
| | | // 5. Right Rip Size Min um |
| | | strTemp = m_JudgementInfo.GetItemText(nRowIdx++, nColIdx); |
| | | rip.m_nRightRipSizeMin_um = _wtoi(strTemp); |
| | | |
| | | // 6. Right Rip Size Max um |
| | | strTemp = m_JudgementInfo.GetItemText(nRowIdx++, nColIdx); |
| | | rip.m_nRightRipSizeMax_um = _wtoi(strTemp); |
| | | } |
| | | } |
| | | } |
| | | } |
| | |
| | | { |
| | | UINT nID = GetFocus()->GetDlgCtrlID(); |
| | | |
| | | SetSideRadioExclusive(nID); |
| | | |
| | | UpdateRecipe(TRUE); |
| | | |
| | | ChangViewCdmSide(nID); |
| | | RefreshRadioStates(); |
| | | } |
| | | |
| | | |
| | |
| | | { |
| | | UINT nID = GetFocus()->GetDlgCtrlID(); |
| | | |
| | | Fill_SideInsInfo(TRUE); // Get Data.. |
| | | Fill_SideInsInfo(TRUE); |
| | | Fill_JudgementInfo(TRUE); |
| | | |
| | | ChangInsTypeSide(nID); |
| | | RefreshRadioStates(); |
| | | } |
| | | |
| | | void CViewMain_Recipe::ClickButtonLang() |
| | |
| | | #endif // HALCON_VISION_KEY |
| | | } |
| | | |
| | | void CViewMain_Recipe::SetSideRadioExclusive(UINT nSelId) |
| | | void CViewMain_Recipe::RefreshRadioStates() |
| | | { |
| | | static const UINT kIds[] = { |
| | | // 内部映射 lambda:枚举 -> 控件 ID |
| | | auto InsTypeToCtrlId = [](eViewCmdInsType t) -> UINT { |
| | | switch (t) { |
| | | case eRcp_InsType_Chip: return IDC_RDO_INSTYPE_CHIP; |
| | | case eRcp_InsType_Crack: return IDC_RDO_INSTYPE_CRACK; |
| | | case eRcp_InsType_Burr: return IDC_RDO_INSTYPE_BURR; |
| | | case eRcp_InsType_Chamfer: return IDC_RDO_INSTYPE_CHAMFER; |
| | | case eRcp_InsType_In_Chip: return IDC_RDO_INSTYPE_IN_CHIP; |
| | | case eRcp_InsType_In_Crack: return IDC_RDO_INSTYPE_IN_CRACK; |
| | | case eRcp_InsType_In_Burr: return IDC_RDO_INSTYPE_IN_BURR; |
| | | case eRcp_InsType_In_Chamfer: return IDC_RDO_INSTYPE_IN_CHAMFER; |
| | | case eRcp_InsType_TopCorner: return IDC_RDO_INSTYPE_TOP_CORNER; |
| | | case eRcp_InsType_BotCorner: return IDC_RDO_INSTYPE_BOT_CORNER; |
| | | case eRcp_InsType_RipThickness: return IDC_RDO_INSTYPE_RIP_THICKNESS; |
| | | default: return 0; |
| | | } |
| | | }; |
| | | |
| | | auto SideToCtrlId = [](eViewCmdSide s) -> UINT { |
| | | switch (s) { |
| | | case eRcp_SideRD_A: return IDC_RDO_SIDE_A_TOP; |
| | | case eRcp_SideRD_B: return IDC_RDO_SIDE_B_TOP; |
| | | case eRcp_SideRD_C: return IDC_RDO_SIDE_C_TOP; |
| | | case eRcp_SideRD_D: return IDC_RDO_SIDE_D_TOP; |
| | | case eRcp_SideRD_A_DN: return IDC_RDO_SIDE_A_BOT; |
| | | case eRcp_SideRD_B_DN: return IDC_RDO_SIDE_B_BOT; |
| | | case eRcp_SideRD_C_DN: return IDC_RDO_SIDE_C_BOT; |
| | | case eRcp_SideRD_D_DN: return IDC_RDO_SIDE_D_BOT; |
| | | case eRcp_SideRD_A_RIP: return IDC_RDO_SIDE_A_RIP; |
| | | case eRcp_SideRD_B_RIP: return IDC_RDO_SIDE_B_RIP; |
| | | case eRcp_SideRD_C_RIP: return IDC_RDO_SIDE_C_RIP; |
| | | case eRcp_SideRD_D_RIP: return IDC_RDO_SIDE_D_RIP; |
| | | default: return 0; |
| | | } |
| | | }; |
| | | |
| | | const UINT nInsIds[] = { |
| | | IDC_RDO_INSTYPE_CHIP, IDC_RDO_INSTYPE_CRACK, IDC_RDO_INSTYPE_BURR, |
| | | IDC_RDO_INSTYPE_CHAMFER, IDC_RDO_INSTYPE_IN_CHIP, IDC_RDO_INSTYPE_IN_CRACK, |
| | | IDC_RDO_INSTYPE_IN_BURR, IDC_RDO_INSTYPE_IN_CHAMFER, |
| | | IDC_RDO_INSTYPE_TOP_CORNER, IDC_RDO_INSTYPE_BOT_CORNER, |
| | | IDC_RDO_INSTYPE_RIP_THICKNESS |
| | | }; |
| | | |
| | | const UINT nSideIds[] = { |
| | | IDC_RDO_SIDE_A_TOP, IDC_RDO_SIDE_B_TOP, IDC_RDO_SIDE_C_TOP, IDC_RDO_SIDE_D_TOP, |
| | | IDC_RDO_SIDE_A_BOT, IDC_RDO_SIDE_B_BOT, IDC_RDO_SIDE_C_BOT, IDC_RDO_SIDE_D_BOT, |
| | | IDC_RDO_SIDE_A_RIP, IDC_RDO_SIDE_B_RIP, IDC_RDO_SIDE_C_RIP, IDC_RDO_SIDE_D_RIP |
| | | }; |
| | | |
| | | for (UINT id : kIds) { |
| | | if (CButton* p = (CButton*)GetDlgItem(id)) { |
| | | p->SetCheck(id == nSelId ? 1 : 0); |
| | | const UINT nSelIns = InsTypeToCtrlId(m_eSelectInsType); |
| | | for (UINT id : nInsIds) { |
| | | if (auto* p = (CButton*)GetDlgItem(id)) { |
| | | p->SetCheck(id == nSelIns ? 1 : 0); |
| | | } |
| | | } |
| | | |
| | | const UINT nSelSide = SideToCtrlId(m_eSelectSide); |
| | | for (UINT id : nSideIds) { |
| | | if (auto* p = (CButton*)GetDlgItem(id)) { |
| | | p->SetCheck(id == nSelSide ? 1 : 0); |
| | | } |
| | | } |
| | | } |
| | |
| | | BOOL WriteLinkFile(CString strFilePath); |
| | | void ChangeRecipe(); |
| | | BOOL ReadRecipe(CString strRecipe); |
| | | void SetSideRadioExclusive(UINT nSelId); |
| | | void RefreshRadioStates(); |
| | | |
| | | public: |
| | | void UpdateRecipe(BOOL bGetData, int type = 0); |
| | |
| | | #define IDC_RDO_SIDE_B_BOT 1814 |
| | | #define IDC_RDO_SIDE_C_BOT 1815 |
| | | #define IDC_RDO_SIDE_D_BOT 1816 |
| | | #define IDC_RDO_INSTYPE_CHIPCRACK 1817 |
| | | #define IDC_RDO_INSTYPE_CHIP 1817 |
| | | #define IDC_RDO_INSTYPE_BURR 1818 |
| | | #define IDC_RDO_INSTYPE_BURR2 1819 |
| | | #define IDC_RDO_INSTYPE_CHAMFER 1819 |
| | | #define IDC_RDO_INSTYPE_TOP_CORNER 1820 |
| | | #define IDC_RDO_INSTYPE_BOT_CORNER 1821 |
| | | #define IDC_RDO_INSTYPE_CRACK 1822 |
| | | #define IDC_RDO_SIDE_A_RIP 1823 |
| | | #define IDC_RDO_SIDE_B_RIP 1824 |
| | | #define IDC_RDO_INSTYPE_CF_CHIPCRACK 1825 |
| | | #define IDC_RDO_INSTYPE_IN_CHIP 1825 |
| | | #define IDC_RDO_INSTYPE_CF_BURR 1826 |
| | | #define IDC_RDO_INSTYPE_IN_BURR 1826 |
| | | #define IDC_RDO_INSTYPE_IN_CRACK 1827 |
| | | #define IDC_RDO_INSTYPE_IN_BURR2 1828 |
| | | #define IDC_RDO_INSTYPE_IN_CHAMFER 1828 |
| | | #define IDC_RDO_SIDE_C_RIP 1829 |
| | | #define IDC_RDO_SIDE_D_BOT2 1830 |
| | | #define IDC_RDO_SIDE_D_RIP 1830 |
| | | #define IDC_RDO_SIDE_A_RIP 1817 |
| | | #define IDC_RDO_SIDE_B_RIP 1818 |
| | | #define IDC_RDO_SIDE_C_RIP 1819 |
| | | #define IDC_RDO_SIDE_D_RIP 1820 |
| | | #define IDC_RDO_INSTYPE_CHIPCRACK 1821 |
| | | #define IDC_RDO_INSTYPE_CHIP 1822 |
| | | #define IDC_RDO_INSTYPE_BURR 1823 |
| | | #define IDC_RDO_INSTYPE_BURR2 1824 |
| | | #define IDC_RDO_INSTYPE_CHAMFER 1825 |
| | | #define IDC_RDO_INSTYPE_TOP_CORNER 1826 |
| | | #define IDC_RDO_INSTYPE_BOT_CORNER 1827 |
| | | #define IDC_RDO_INSTYPE_CRACK 1828 |
| | | #define IDC_RDO_INSTYPE_CF_CHIPCRACK 1829 |
| | | #define IDC_RDO_INSTYPE_IN_CHIP 1830 |
| | | #define IDC_RDO_INSTYPE_CF_BURR 1831 |
| | | #define IDC_RDO_INSTYPE_IN_BURR 1832 |
| | | #define IDC_RDO_INSTYPE_IN_CRACK 1833 |
| | | #define IDC_RDO_INSTYPE_IN_CHAMFER 1834 |
| | | #define IDC_RDO_INSTYPE_RIP_THICKNESS 1835 |
| | | #define IDC_RDO_INSTYPE_RIP_THICKNESS2 1860 |
| | | #define ID_PROFILE_CHECKALL 32782 |
| | | #define ID_PROFILE_CLEARALL 32783 |
| | | #define ID_PROFILE_CURRENTX 32784 |