| | |
| | | #include "StdAfx.h" |
| | | #include "StdAfx.h" |
| | | #include "InspectCamera.h" |
| | | #include "GlassRecipe.h" |
| | | #include "HardwareSettings.h" |
| | |
| | | #endif // USE_WEBSOCKET |
| | | |
| | | #define BOUNDARY_GLASSSTARTWIDTH 160 |
| | | #define BOUNDARYHORIZ_LEVELDIST 8 // 荐乞 版拌急阑 茫阑 锭狼 厚背芭府 |
| | | #define BOUNDARYHORIZ_LEVELDIST 8 // 수평 경계선을 찾을 때의 비교거리 |
| | | #define TIME_WAIT_GLASS_START 3000 |
| | | |
| | | #define align_4byte(in) ((in + 3)/4)*4 |
| | | #define RAD_TO_DEGREE (double)(180.0f / 3.1415926535f) |
| | | |
| | | CInspectCamera::CInspectCamera(int iCam) |
| | | { |
| | | { |
| | | m_iCamera = iCam; |
| | | m_pThreadControl = new CThreadControl(); |
| | | m_pRecipe = NULL; |
| | |
| | | ReleaseThread(); |
| | | ReleaseFullBuffer(); |
| | | |
| | | if(m_pDefectControl != NULL) |
| | | if (m_pDefectControl != NULL) |
| | | delete m_pDefectControl; |
| | | m_pDefectControl = NULL; |
| | | |
| | |
| | | |
| | | void CInspectCamera::ReleaseThread() |
| | | { |
| | | m_bExitThread = TRUE; |
| | | if(m_pThreadControl != NULL) |
| | | m_bExitThread = TRUE; |
| | | if (m_pThreadControl != NULL) |
| | | { |
| | | m_pThreadControl->ReleaseThreadControl(); |
| | | Sleep(100); |
| | |
| | | } |
| | | } |
| | | |
| | | int CInspectCamera::InitInspect(int nThread,int maxDefect) |
| | | int CInspectCamera::InitInspect(int nThread, int maxDefect) |
| | | { |
| | | m_pThreadControl->InitThreadControl(nThread,this); |
| | | m_pThreadControl->InitThreadControl(nThread, this); |
| | | |
| | | m_pDefectControl->InitDefectStorage(maxDefect); |
| | | |
| | |
| | | m_bExitThread = FALSE; |
| | | |
| | | CCameraSettings* pCamSetting = m_pHardparm->GetCameraSettings(m_iCamera, m_iScan); |
| | | if(pCamSetting == NULL || m_pGlassData == NULL) |
| | | if (pCamSetting == NULL || m_pGlassData == NULL) |
| | | { |
| | | g_pLog->DisplayMessage(_T("HW Setting Error.. or Glass Data Error..")); |
| | | return FALSE; |
| | |
| | | m_dPixelSizeX = pCamSetting->m_dConvResolution[m_pGlassData->GetStageNo()]; |
| | | m_dPixelSizeY = pCamSetting->m_dScanResolution[m_pGlassData->GetStageNo()]; |
| | | |
| | | CSide_Data* pSideData = m_pGlassData->GetSideData(pCamSetting->m_eDimension); |
| | | CSide_Data* pSideData = m_pGlassData->GetSideData(pCamSetting->m_eDimension); |
| | | pSideData->m_dPixelSizeX = m_dPixelSizeX; |
| | | pSideData->m_dPixelSizeY = m_dPixelSizeY; |
| | | |
| | | #if HALCON_VISION_KEY |
| | | CBlSideData *pBlSideData = BlVision_GetVisionRecipe()->getSideData(pCamSetting->m_eDimension); |
| | | CBlSideData* pBlSideData = BlVision_GetVisionRecipe()->getSideData(pCamSetting->m_eDimension); |
| | | if (NULL != pBlSideData) { |
| | | pBlSideData->m_mapSideLineInf.clear(); |
| | | } |
| | |
| | | |
| | | BOOL CInspectCamera::ScanStartThread() |
| | | { |
| | | if(m_pThreadControl == NULL) |
| | | return FALSE; |
| | | if (m_pThreadControl == NULL) |
| | | return FALSE; |
| | | |
| | | int nThread = m_pThreadControl->StartThreadControl(); |
| | | if(nThread <= 0) |
| | | { |
| | | if (nThread <= 0) |
| | | { |
| | | return FALSE; |
| | | } |
| | | |
| | |
| | | |
| | | BOOL CInspectCamera::GetCheckFrame(stFrameIndex stFrame) |
| | | { |
| | | CCameraSettings *pCamera = m_pHardparm->GetCameraSettings(m_iCamera,stFrame.nScanIdx); |
| | | if(pCamera == NULL) |
| | | CCameraSettings* pCamera = m_pHardparm->GetCameraSettings(m_iCamera, stFrame.nScanIdx); |
| | | if (pCamera == NULL) |
| | | return FALSE; |
| | | |
| | | DimensionDir emDim = pCamera->m_eDimension; |
| | | CSide_Data* pSideData = m_pGlassData->GetSideData(emDim); |
| | | if(pSideData == NULL) |
| | | if (pSideData == NULL) |
| | | return FALSE; |
| | | |
| | | int nFrameHeight = pCamera->m_FrameSize.cy; |
| | | int nStartFrame = pSideData->m_nGlassStartLine/nFrameHeight; |
| | | |
| | | if(nStartFrame > stFrame.nFrameIdx) |
| | | int nFrameHeight = pCamera->m_FrameSize.cy; |
| | | int nStartFrame = pSideData->m_nGlassStartLine / nFrameHeight; |
| | | |
| | | if (nStartFrame > stFrame.nFrameIdx) |
| | | return TRUE; |
| | | |
| | | return FALSE; |
| | | } |
| | | |
| | | ERR_FIND_GLASSSTARTLINE CInspectCamera::IsGlassStartLine(int iThread,int &iScan) |
| | | ERR_FIND_GLASSSTARTLINE CInspectCamera::IsGlassStartLine(int iThread, int& iScan) |
| | | { |
| | | iScan = m_iScan; |
| | | |
| | |
| | | |
| | | stFrame.nScanIdx = m_iScan; |
| | | |
| | | if(m_bFindGlassStart[stFrame.nScanIdx] == TRUE) |
| | | if (m_bFindGlassStart[stFrame.nScanIdx] == TRUE) |
| | | return ERR_FINDGLASSSTART_SUCCESS; |
| | | |
| | | // 磊悼老锭 橇饭烙 荐甫 面盒洒 棱栏搁 巩力啊 救登绰芭 鞍促父... 橇饭烙 荐啊 何练窍搁 咯扁辑 公茄栏肺 吧覆.. 弊府绊 矫累急 茫疽栏搁 弊成 逞绢啊搁 登瘤 臼唱? |
| | | if(m_pGrabber->GetGrabFrameCount() < 1) |
| | | // 자동일때 프레임 수를 충분히 잡으면 문제가 안되는거 같다만... 프레임 수가 부족하면 여기서 무한으로 걸림.. 그리고 시작선 찾았으면 그냥 넘어가면 되지 않나? |
| | | if (m_pGrabber->GetGrabFrameCount() < 1) |
| | | { |
| | | Sleep(0); |
| | | return ERR_FINDGLASSSTART_FAIL; |
| | |
| | | return ERR_FINDGLASSSTART_SUCCESS; |
| | | */ |
| | | |
| | | if(iThread != 0) |
| | | return ERR_FINDGLASSSTART_FAIL; |
| | | |
| | | DimensionDir emDim = GetDimension(stFrame.nScanIdx); |
| | | if (iThread != 0) |
| | | return ERR_FINDGLASSSTART_FAIL; |
| | | |
| | | DimensionDir emDim = GetDimension(stFrame.nScanIdx); |
| | | |
| | | iScan = stFrame.nScanIdx; |
| | | |
| | | if(FindGlassStartLine(emDim,stFrame) == TRUE) |
| | | if (FindGlassStartLine(emDim, stFrame) == TRUE) |
| | | { |
| | | g_pLog->DisplayMessage(_T("Find Start Line Success!")); |
| | | |
| | | ScanRegionSet(stFrame); |
| | | ScanRegionSet(stFrame); |
| | | m_bFindGlassStart[stFrame.nScanIdx] = TRUE; |
| | | |
| | | m_MsgJob.nState = 1; |
| | | m_MsgJob.nDispLine = 0; |
| | | m_MsgJob.nSide = (int)emDim; |
| | | CSide_Data* pSideData = m_pGlassData->GetSideData(emDim); |
| | | if(pSideData != NULL) |
| | | if (pSideData != NULL) |
| | | m_MsgJob.nDispLine = pSideData->m_nGlassStartLine; |
| | | |
| | | ::SendMessage(m_hWndViewScan, WM_POCESS_STATUS,(WPARAM)&m_MsgJob, (int)emDim); |
| | | ::SendMessage(m_hWndViewScan, WM_POCESS_STATUS, (WPARAM)&m_MsgJob, (int)emDim); |
| | | |
| | | return ERR_FINDGLASSSTART_SUCCESS; |
| | | } |
| | | else |
| | | { |
| | | { |
| | | return ERR_FINDGLASSSTART_FIND_FAIL; |
| | | } |
| | | |
| | | return ERR_FINDGLASSSTART_FAIL; |
| | | } |
| | | |
| | | BOOL CInspectCamera::OnThreadRun(int iThread, CInspectThread *pInspectThread) |
| | | BOOL CInspectCamera::OnThreadRun(int iThread, CInspectThread* pInspectThread) |
| | | { |
| | | if(m_pRecipe == NULL) |
| | | return FALSE; |
| | | if(m_pHardparm == NULL) |
| | | if (m_pRecipe == NULL) |
| | | return FALSE; |
| | | if(m_pGlassData == NULL) |
| | | if (m_pHardparm == NULL) |
| | | return FALSE; |
| | | if(m_pGrabber == NULL) |
| | | if (m_pGlassData == NULL) |
| | | return FALSE; |
| | | if (m_pGrabber == NULL) |
| | | return FALSE; |
| | | |
| | | while(TRUE) |
| | | while (TRUE) |
| | | { |
| | | Sleep(1); // Sleep 1肺 吧绢拎具 茄促... 0栏肺 吧搁 八荤啊 救瞪嫐啊 乐澜.. 恐? |
| | | Sleep(1); // Sleep 1로 걸어줘야 한다... 0으로 걸면 검사가 안될가 있음.. 왜? |
| | | |
| | | if(GetCheckExit() == TRUE) |
| | | if (GetCheckExit() == TRUE) |
| | | { |
| | | g_pLog->DisplayMessage(_T("cam %d, Thread %d Thread Exit"),m_iCamera,iThread); |
| | | g_pLog->DisplayMessage(_T("cam %d, Thread %d Thread Exit"), m_iCamera, iThread); |
| | | break; |
| | | } |
| | | } |
| | | |
| | | // 1. 0锅 Thread肺 Start Line 茫扁 |
| | | // 1. 0번 Thread로 Start Line 찾기 |
| | | int iRetScan; |
| | | switch(IsGlassStartLine(iThread,iRetScan)) |
| | | switch (IsGlassStartLine(iThread, iRetScan)) |
| | | { |
| | | case ERR_FINDGLASSSTART_FAIL: |
| | | continue; |
| | |
| | | m_pGrabber->GrabScanStop(); |
| | | m_pGrabber->ClearGrabIdx(); |
| | | m_bExitThread = TRUE; |
| | | g_pLog->DisplayMessage(_T("%s Process Find Glass StartLine Fail"),PANEL_SIDE[GetDimension(iRetScan)]); |
| | | g_pLog->DisplayMessage(_T("%s Process Find Glass StartLine Fail"), PANEL_SIDE[GetDimension(iRetScan)]); |
| | | |
| | | m_MsgJob.nState = 1; |
| | | m_MsgJob.nDispLine = 0; |
| | | m_MsgJob.nSide = (int)GetDimension(m_iScan); |
| | | ::SendMessage(m_hWndViewScan, WM_POCESS_STATUS,(WPARAM)&m_MsgJob, (int)m_MsgJob.nSide); |
| | | ::SendMessage(m_hWndViewScan, WM_POCESS_STATUS, (WPARAM)&m_MsgJob, (int)m_MsgJob.nSide); |
| | | continue; |
| | | break; |
| | | } |
| | | |
| | | // 2. Start Line阑 茫疽栏搁, 茄橇饭烙究 波郴辑 八荤 矫累 |
| | | } |
| | | |
| | | // 2. Start Line을 찾았으면, 한프레임씩 꺼내서 검사 시작 |
| | | stFrameIndex stFrame = m_pGrabber->GetGrabFrame(); |
| | | if(stFrame.nScanIdx < 0 || stFrame.nFrameIdx < 0) |
| | | if (stFrame.nScanIdx < 0 || stFrame.nFrameIdx < 0) |
| | | continue; |
| | | |
| | | DimensionDir emDim = GetDimension(stFrame.nScanIdx); |
| | |
| | | |
| | | m_pGlassData->GetSideData(emDim)->SetFrameProc(stFrame.nFrameIdx); |
| | | |
| | | // 3. Start Line Frame 焊促 捞傈牢瘤 眉农.. |
| | | if(CheckStartLineFrame(emDim,stFrame.nFrameIdx) == FALSE) |
| | | // 3. Start Line Frame 보다 이전인지 체크.. |
| | | if (CheckStartLineFrame(emDim, stFrame.nFrameIdx) == FALSE) |
| | | { |
| | | g_pLog->DisplayMessage(_T("Check Start Line Frame.. %s : %d"),g_SideName[(int) emDim], stFrame.nFrameIdx); |
| | | g_pLog->DisplayMessage(_T("Check Start Line Frame.. %s : %d"), g_SideName[(int)emDim], stFrame.nFrameIdx); |
| | | continue; |
| | | } |
| | | |
| | |
| | | |
| | | SetFrameFinish(stFrame.nScanIdx, stFrame.nFrameIdx); |
| | | |
| | | BOOL bEnd = CheckThreadEnd(iThread,stFrame); |
| | | |
| | | if(stFrame.nFrameIdx % 5 == 0 && bEnd == FALSE && m_pGlassData->GetSideData(emDim)->m_bFindGlassEndLine == FALSE) |
| | | BOOL bEnd = CheckThreadEnd(iThread, stFrame); |
| | | |
| | | if (stFrame.nFrameIdx % 5 == 0 && bEnd == FALSE && m_pGlassData->GetSideData(emDim)->m_bFindGlassEndLine == FALSE) |
| | | { |
| | | m_MsgJob.nState = 1; |
| | | m_MsgJob.nDispLine = stFrame.nFrameIdx * m_nFrameHeight; |
| | |
| | | } |
| | | } |
| | | |
| | | g_pLog->DisplayMessage(_T("Camera %d-%d Thread End"),m_iCamera,iThread); |
| | | g_pLog->DisplayMessage(_T("Camera %d-%d Thread End"), m_iCamera, iThread); |
| | | |
| | | return TRUE; |
| | | } |
| | |
| | | pBlSideData->m_mBotMark.y = pSideData->m_ptBotMark_FindResult.y; |
| | | } |
| | | |
| | | //添加此功能 |
| | | //警속늪묘콘 |
| | | pBlSideData->m_nStartLine = pSideData->m_nGlassStartLine; |
| | | pBlSideData->m_nEndLine = pSideData->m_nGlassEndLine; |
| | | pBlSideData->m_vDispVisionResult.clear(); |
| | |
| | | for (int i = 0; i < ngNum; i++) { |
| | | NgInfo ng = ngArray[i]; |
| | | |
| | | //if (ng.isRes) continue; //结果OK,继续 |
| | | //这里添加结果 |
| | | //if (ng.isRes) continue; //써벎OK,셨崎 |
| | | //侶쟁警속써벎 |
| | | |
| | | if (5 == ng.ngType && (ng.result < ng.minValue || ng.result > ng.maxValue)) |
| | | { |
| | | |
| | | |
| | | CDefect_Info defectInfo; |
| | | defectInfo.m_iFrameIdx = stFrame.nFrameIdx; // stFrame.nFrameIdx; |
| | | defectInfo.m_nCamID = m_iCamera; |
| | |
| | | defectInfo.m_rtDefectPos_pxl = CRect(ng.xPosPxl, ng.yPosPxl, ng.xPosPxl + 50, ng.yPosPxl + 10); |
| | | defectInfo.m_DefectLoc = DefectLoc_Corner_Chamfer; |
| | | |
| | | |
| | | |
| | | if (m_pDefectControl != NULL) |
| | | m_pDefectControl->ExtractDefect_CorChamfer(eDim, m_iCamera, stFrame.nScanIdx, DefectLoc_Corner_Chamfer, defectInfo, (int)(ng.result)); |
| | | m_pDefectControl->ExtractDefect_CorChamfer(eDim, m_iCamera, stFrame.nScanIdx, DefectLoc_Corner_Chamfer, defectInfo, (int)(ng.result)); |
| | | } |
| | | } |
| | | #endif // HALCON_VISION_KEY |
| | | } |
| | | |
| | | BOOL CInspectCamera::CheckThreadEnd(int iThread,stFrameIndex stFrame) |
| | | BOOL CInspectCamera::CheckThreadEnd(int iThread, stFrameIndex stFrame) |
| | | { |
| | | int iScan = stFrame.nScanIdx; |
| | | |
| | | CSingleLock myLoc(&m_csThreadEnd); |
| | | CSingleLock myLoc(&m_csThreadEnd); |
| | | myLoc.Lock(); |
| | | |
| | | // 捞固 场抄 Thread.. |
| | | if(m_iThreadEnd[iScan][iThread] == 1) |
| | | { |
| | | int iScan = stFrame.nScanIdx; |
| | | if (m_iThreadEnd[iScan][iThread] == 1) { |
| | | myLoc.Unlock(); |
| | | return FALSE; |
| | | return FALSE; |
| | | } |
| | | |
| | | BOOL bEnd = FALSE; |
| | | |
| | | if(CheckProcessEnd(iThread,stFrame) == TRUE) |
| | | { |
| | | BOOL bEnd = FALSE; |
| | | if (CheckProcessEnd(iThread, stFrame) == TRUE) { |
| | | m_iThreadEnd[iScan][iThread] = 1; |
| | | bEnd = TRUE; |
| | | myLoc.Unlock(); |
| | | } |
| | | |
| | | if(bEnd == TRUE) |
| | | { |
| | | if (bEnd == TRUE) { |
| | | DimensionDir emDim = GetDimension(iScan); |
| | | |
| | | m_pGlassData->GetSideData(emDim)->m_bInspection_Complete = TRUE; |
| | | |
| | | g_pLog->DisplayMessage(_T("%s Thread %d Process End : Scan %d, Frame %d"),PANEL_SIDE[emDim],iThread,iScan,stFrame.nFrameIdx); |
| | | |
| | | if(GetThreadEndCount(iScan) == MAX_THREAD) |
| | | { |
| | | g_pLog->DisplayMessage(_T("%s Thread %d Process End : Scan %d, Frame %d"), PANEL_SIDE[emDim], iThread, iScan, stFrame.nFrameIdx); |
| | | |
| | | if (GetThreadEndCount(iScan) == MAX_THREAD) { |
| | | myLoc.Lock(); |
| | | SaveFullImageCopy(iScan); |
| | | myLoc.Unlock(); |
| | | |
| | | g_pLog->DisplayMessage(_T("%s Scan Process All End"),PANEL_SIDE[emDim]); |
| | | g_pLog->DisplayMessage(_T("%s Scan Process All End"), PANEL_SIDE[emDim]); |
| | | |
| | | FinallyVisionProc(emDim); |
| | | if(m_pII2S != NULL) |
| | | m_pII2S->II2S_InspectionEnd(m_iCamera,iScan); |
| | | |
| | | /* |
| | | // Waiting All Frame Finish.. |
| | | DWORD dwTickCount = GetTickCount(); |
| | | while(GetTickCount() - dwTickCount < 5000) |
| | | { |
| | | if(CheckAllFrameFinish(iScan) == TRUE) |
| | | break; |
| | | if (m_pII2S != NULL) { |
| | | m_pII2S->II2S_InspectionEnd(m_iCamera, iScan); |
| | | } |
| | | */ |
| | | |
| | | //m_MsgJob.nState = 2; |
| | | //m_MsgJob.nSide = (int)emDim; |
| | | //m_MsgJob.nDispLine = stFrame.nFrameIdx * m_nFrameHeight; |
| | | //::SendMessage(m_hWndViewScan, WM_POCESS_STATUS,(WPARAM)&m_MsgJob, (int)emDim); |
| | | } |
| | | } |
| | | } |
| | | |
| | | myLoc.Unlock(); |
| | |
| | | int CInspectCamera::GetThreadEndCount(int iScan) |
| | | { |
| | | int nCount = 0; |
| | | for(int i=0;i<MAX_THREAD;i++) |
| | | if(m_iThreadEnd[iScan][i] == 1) |
| | | for (int i = 0; i < MAX_THREAD; i++) |
| | | if (m_iThreadEnd[iScan][i] == 1) |
| | | nCount++; |
| | | |
| | | return nCount; |
| | |
| | | |
| | | m_nFrameFinishIdx[nCurrentScanIdx] = -1; |
| | | |
| | | for(int i=0; i<MAX_FRAM_COUNT; i++) |
| | | for (int i = 0; i < MAX_FRAM_COUNT; i++) { |
| | | m_bFrameFinish[nCurrentScanIdx][i] = FALSE; |
| | | } |
| | | |
| | | cslocalLock.Unlock(); |
| | | } |
| | |
| | | CSingleLock cslocalLock(&m_csFrameFinishCheck); |
| | | cslocalLock.Lock(); |
| | | |
| | | if(m_nFrameFinishIdx[nCurrentScanIdx] == -1) |
| | | if (m_nFrameFinishIdx[nCurrentScanIdx] == -1) { |
| | | cslocalLock.Unlock(); |
| | | return FALSE; |
| | | } |
| | | |
| | | for(int i=0; i<m_nFrameFinishIdx[nCurrentScanIdx]; i++) |
| | | if(m_bFrameFinish[nCurrentScanIdx][i] == FALSE) |
| | | for (int i = 0; i < m_nFrameFinishIdx[nCurrentScanIdx]; i++) { |
| | | if (m_bFrameFinish[nCurrentScanIdx][i] == FALSE) { |
| | | cslocalLock.Unlock(); |
| | | return FALSE; |
| | | } |
| | | } |
| | | |
| | | cslocalLock.Unlock(); |
| | | return TRUE; |
| | | } |
| | | |
| | |
| | | double dX_um = GetPixelToUm_X(ptEnd_pxl.x - ptStart_pxl.x); |
| | | double dY_um = GetPixelToUm_Y(ptEnd_pxl.y - ptStart_pxl.y); |
| | | |
| | | return sqrt((dX_um*dX_um) + (dY_um*dY_um)); |
| | | return sqrt((dX_um * dX_um) + (dY_um * dY_um)); |
| | | } |
| | | |
| | | BOOL CInspectCamera::GetAlignRotate(DimensionDir emDim, CPoint ptSetTopMark, CPoint ptSetBotMark, CRect rtSetArea, CRect& bRotateArea) |
| | | { |
| | | if(rtSetArea.IsRectEmpty() || rtSetArea.IsRectNull()) |
| | | if (rtSetArea.IsRectEmpty() || rtSetArea.IsRectNull()) |
| | | return FALSE; |
| | | |
| | | if(m_pGlassData == NULL) |
| | | if (m_pGlassData == NULL) |
| | | return FALSE; |
| | | |
| | | CSide_Data* pSideData = m_pGlassData->GetSideData(emDim); |
| | | |
| | | if(pSideData == NULL) |
| | | if (pSideData == NULL) |
| | | return FALSE; |
| | | |
| | | if(pSideData->m_bTopMark_Find == FALSE || pSideData->m_bBotMark_Find == FALSE) |
| | | if (pSideData->m_bTopMark_Find == FALSE || pSideData->m_bBotMark_Find == FALSE) |
| | | return FALSE; |
| | | |
| | | CPoint ptSet_Area = rtSetArea.CenterPoint(); |
| | | |
| | | double dSet_DiffX = (double) (ptSetBotMark.x - ptSetTopMark.x); |
| | | double dSet_DiffY = (double) (ptSetBotMark.y - ptSetTopMark.y); |
| | | double dset_T_Rad = (dSet_DiffY == 0.0) ? 0.0 : atan(dSet_DiffX/dSet_DiffY); |
| | | double dSet_DiffX = (double)(ptSetBotMark.x - ptSetTopMark.x); |
| | | double dSet_DiffY = (double)(ptSetBotMark.y - ptSetTopMark.y); |
| | | double dset_T_Rad = (dSet_DiffY == 0.0) ? 0.0 : atan(dSet_DiffX / dSet_DiffY); |
| | | |
| | | CPoint ptFind_TopMark = pSideData->m_ptTopMark_FindResult; |
| | | CPoint ptFind_BotMark = pSideData->m_ptBotMark_FindResult; |
| | | |
| | | double dFind_DiffX = (double) (ptFind_BotMark.x - ptFind_TopMark.x); |
| | | double dFind_DiffY = (double) (ptFind_BotMark.y - ptFind_TopMark.y); |
| | | double dFind_T_Rad = (dFind_DiffY == 0.0) ? 0.0 : atan(dFind_DiffX/dFind_DiffY); |
| | | double dFind_DiffX = (double)(ptFind_BotMark.x - ptFind_TopMark.x); |
| | | double dFind_DiffY = (double)(ptFind_BotMark.y - ptFind_TopMark.y); |
| | | double dFind_T_Rad = (dFind_DiffY == 0.0) ? 0.0 : atan(dFind_DiffX / dFind_DiffY); |
| | | |
| | | double dDiff_T_Rad = dFind_T_Rad - dset_T_Rad; |
| | | |
| | | double dMarkToArea_X_pxl = ptSet_Area.x - ptSetTopMark.x; |
| | | double dMarkToArea_Y_pxl = ptSet_Area.y - ptSetTopMark.y; |
| | | double dMarkToArea_Distance_pxl = sqrt((dMarkToArea_X_pxl*dMarkToArea_X_pxl) + (dMarkToArea_Y_pxl*dMarkToArea_Y_pxl)); |
| | | double dMarkToArea_T_Rad = (dMarkToArea_Y_pxl == 0.0) ? 0.0 : atan(dMarkToArea_X_pxl/dMarkToArea_Y_pxl); |
| | | double dMarkToArea_Distance_pxl = sqrt((dMarkToArea_X_pxl * dMarkToArea_X_pxl) + (dMarkToArea_Y_pxl * dMarkToArea_Y_pxl)); |
| | | double dMarkToArea_T_Rad = (dMarkToArea_Y_pxl == 0.0) ? 0.0 : atan(dMarkToArea_X_pxl / dMarkToArea_Y_pxl); |
| | | |
| | | double dRotateArea_T_Rad = dMarkToArea_T_Rad + dDiff_T_Rad; |
| | | |
| | |
| | | double dRotate_X_pxl = sin(dRotateArea_T_Rad) * dMarkToArea_Distance_pxl * dDirection; |
| | | double dRotate_Y_pxl = cos(dRotateArea_T_Rad) * dMarkToArea_Distance_pxl * dDirection; |
| | | |
| | | bRotateArea.left = bRotateArea.right = (int) ptFind_TopMark.x + dRotate_X_pxl; |
| | | bRotateArea.top = bRotateArea.bottom = (int) ptFind_TopMark.y + dRotate_Y_pxl; |
| | | bRotateArea.left = bRotateArea.right = ptFind_TopMark.x + (LONG)dRotate_X_pxl; |
| | | bRotateArea.top = bRotateArea.bottom = ptFind_TopMark.y + (LONG)dRotate_Y_pxl; |
| | | |
| | | bRotateArea.InflateRect(rtSetArea.Width()/2, rtSetArea.Height()/2); |
| | | bRotateArea.InflateRect(rtSetArea.Width() / 2, rtSetArea.Height() / 2); |
| | | |
| | | return TRUE; |
| | | } |
| | | |
| | | BOOL CInspectCamera::CopyRectImg(LPBYTE pOrg,LPBYTE pTgt,CSize szImg,CRect &rectIns) |
| | | BOOL CInspectCamera::CopyRectImg(LPBYTE pOrg, LPBYTE pTgt, CSize szImg, CRect& rectIns) |
| | | { |
| | | if(pOrg == NULL || pTgt == NULL) |
| | | if (pOrg == NULL || pTgt == NULL) |
| | | return FALSE; |
| | | |
| | | int v; |
| | | int dv = 0; |
| | | |
| | | for(v=rectIns.top;v<rectIns.bottom;v++,dv++) |
| | | for (v = rectIns.top; v < rectIns.bottom; v++, dv++) |
| | | { |
| | | CopyMemory(pTgt+dv*rectIns.Width(),pOrg+v*szImg.cx+rectIns.left,rectIns.Width()); |
| | | CopyMemory(pTgt + dv * rectIns.Width(), pOrg + v * szImg.cx + rectIns.left, rectIns.Width()); |
| | | } |
| | | |
| | | return TRUE; |
| | |
| | | |
| | | void CInspectCamera::SaveDebugImage(DimensionDir eDim, stFrameIndex stFrame, COwnerBuffer* pBuffer, CString strFileName) |
| | | { |
| | | if(m_pHardparm == NULL) |
| | | if (m_pHardparm == NULL) |
| | | return; |
| | | |
| | | if(m_pHardparm->m_bUse_SaveDebugImage == FALSE) |
| | | if (m_pHardparm->m_bUse_SaveDebugImage == FALSE) |
| | | return; |
| | | |
| | | // #ifdef _DEBUG |
| | | if(pBuffer == NULL) |
| | | // #ifdef _DEBUG |
| | | if (pBuffer == NULL) |
| | | return; |
| | | |
| | | CString str; |
| | | str.Format(_T("D:\\Inspection\\DebugFullImg\\%s_Side[%s]_Frame[%d].jpg"), strFileName, GetSideName(eDim), stFrame.nFrameIdx); |
| | | |
| | | |
| | | g_pStatus->CheckDirectory(str); |
| | | |
| | | CBufferAttach saveImage(str); |
| | | saveImage.AttachToFile(*pBuffer); |
| | | // #endif |
| | | // #endif |
| | | } |
| | | |
| | | void CInspectCamera::SaveDebugImage(DimensionDir eDim, stFrameIndex stFrame, IplImage* pBuffer, CString strFileName) |
| | | { |
| | | if(m_pHardparm == NULL) |
| | | if (m_pHardparm == NULL) |
| | | return; |
| | | |
| | | if(m_pHardparm->m_bUse_SaveDebugImage == FALSE) |
| | | if (m_pHardparm->m_bUse_SaveDebugImage == FALSE) |
| | | return; |
| | | |
| | | // #ifdef _DEBUG |
| | | if(pBuffer == NULL) |
| | | // #ifdef _DEBUG |
| | | if (pBuffer == NULL) |
| | | return; |
| | | |
| | | CString str; |
| | |
| | | g_pLog->DisplayMessage(_T("SaveDebugImage error...")); |
| | | } |
| | | |
| | | // #endif |
| | | // #endif |
| | | } |
| | | |
| | | void CInspectCamera::SaveDebugImage(DimensionDir eDim, stFrameIndex stFrame, cv::Mat image, CString strFileName) |
| | | { |
| | | if (m_pHardparm == NULL) |
| | | if (m_pHardparm == NULL) { |
| | | return; |
| | | } |
| | | |
| | | if (m_pHardparm->m_bUse_SaveDebugImage == FALSE) |
| | | if (m_pHardparm->m_bUse_SaveDebugImage == FALSE) { |
| | | return; |
| | | } |
| | | |
| | | // #ifdef _DEBUG |
| | | if (image.empty() || image.data == NULL) |
| | | if (image.empty() || image.data == NULL) { |
| | | return; |
| | | } |
| | | |
| | | CString str; |
| | | str.Format(_T("D:\\Inspection\\DebugFullImg\\%s_Side[%s]_Frame[%d].jpg"), strFileName, GetSideName(eDim), stFrame.nFrameIdx); |
| | | |
| | | try |
| | | { |
| | | try { |
| | | g_pStatus->CheckDirectory(str); |
| | | |
| | | USES_CONVERSION; |
| | |
| | | std::string filePath(asciiStr); |
| | | cv::imwrite(filePath, image); |
| | | } |
| | | catch (...) |
| | | { |
| | | catch (...) { |
| | | g_pLog->DisplayMessage(_T("SaveDebugImage error...")); |
| | | } |
| | | |
| | |
| | | |
| | | CString CInspectCamera::GetSideName(DimensionDir eDim) |
| | | { |
| | | switch(eDim) |
| | | switch (eDim) |
| | | { |
| | | case DIMENSION_A: return _T("SideA_UP"); |
| | | break; |
| | |
| | | |
| | | void CInspectCamera::SaveFullImageCopy(int iScan) |
| | | { |
| | | // 4/17 |
| | | // 畴飘合 皋葛府啊 叠妨辑 促款登绰淀.. |
| | | // return; |
| | | |
| | | if(m_pGlassData == NULL) |
| | | if (m_pGlassData == NULL) { |
| | | return; |
| | | if(m_pGrabber == NULL) |
| | | return; |
| | | } |
| | | |
| | | CSingleLock cLock(&m_csSaveimage); |
| | | if (m_pGrabber == NULL) { |
| | | return; |
| | | } |
| | | |
| | | CSingleLock cLock(&m_csSaveimage); |
| | | cLock.Lock(); |
| | | |
| | | DimensionDir eDim = GetDimension(iScan); |
| | | |
| | | CSide_Data* pSideData = m_pGlassData->GetSideData(eDim); |
| | | if(pSideData == NULL) |
| | | if (pSideData == NULL) { |
| | | cLock.Unlock(); |
| | | return; |
| | | } |
| | | |
| | | int nSetEnd = (pSideData->m_nGlassEndLine <= 0) ? pSideData->m_nPreGlassEndLine : pSideData->m_nGlassEndLine; |
| | | int nOffset = 1000; |
| | |
| | | |
| | | g_pLog->DisplayMessage(_T("%s Copy Full Image : nStartLine=%d, nEndLine=%d, nFullSize=%d"), PANEL_SIDE[eDim], nStartLine, nEndLine, nFullSize); |
| | | |
| | | if(nStartLine < 0) |
| | | { |
| | | if (nStartLine < 0) { |
| | | nStartLine = 0; |
| | | } |
| | | |
| | | if(nFullSize <= 0 || nEndLine < 0) |
| | | if (nFullSize <= 0 || nEndLine < 0) { |
| | | cLock.Unlock(); |
| | | return; |
| | | } |
| | | |
| | | //if(nFullSize <= nStartLine) |
| | | // return; |
| | | if (nFullSize <= nStartLine) { |
| | | cLock.Unlock(); |
| | | return; |
| | | } |
| | | |
| | | pINSPECTFULLIMAGE_BUFFER pImgBuf = GetFullImgBuffer(iScan); |
| | | int nFrameWidth,nFrameHeight; |
| | | int nFrameWidth, nFrameHeight; |
| | | |
| | | GetFrameSize(m_iCamera,iScan,nFrameWidth,nFrameHeight); |
| | | GetFrameSize(m_iCamera, iScan, nFrameWidth, nFrameHeight); |
| | | |
| | | if(nFrameWidth <= 0 || nFrameHeight <= 0) |
| | | if (nFrameWidth <= 0 || nFrameHeight <= 0) { |
| | | cLock.Unlock(); |
| | | return; |
| | | } |
| | | |
| | | if(nFullSize/nFrameHeight > m_pGrabber->GetFrameBuffer()->GetFrameCount()) |
| | | nFullSize = (m_pGrabber->GetFrameBuffer()->GetFrameCount()-1)*nFrameHeight; |
| | | if (nFullSize / nFrameHeight > m_pGrabber->GetFrameBuffer()->GetFrameCount()) { |
| | | nFullSize = (m_pGrabber->GetFrameBuffer()->GetFrameCount() - 1) * nFrameHeight; |
| | | } |
| | | |
| | | if(nFullSize <= 100) |
| | | if (nFullSize <= 100) { |
| | | cLock.Unlock(); |
| | | return; |
| | | } |
| | | |
| | | pImgBuf->iCamIdx = m_iCamera; |
| | | pImgBuf->iScanIdx = iScan; |
| | | |
| | | pImgBuf->SetSize(CSize(nFrameWidth,nFullSize)); |
| | | pImgBuf->SetSize(CSize(nFrameWidth, nFullSize)); |
| | | |
| | | g_pLog->DisplayMessage(_T("%s Copy Full Image : nFrameWidth=%d, nFrameHeight=%d"), PANEL_SIDE[eDim], nFrameWidth, nFullSize); |
| | | g_pLog->DisplayMessage(_T("%s Full Image Memory Copy Start : Start[%d]-End[%d]"),PANEL_SIDE[eDim],nStartLine,nEndLine); |
| | | g_pLog->DisplayMessage(_T("%s Full Image Memory Copy Start : Start[%d]-End[%d]"), PANEL_SIDE[eDim], nStartLine, nEndLine); |
| | | |
| | | LPBYTE lpHeader = m_pGrabber->GetFrameHeaderLine(iScan,nStartLine); |
| | | if(lpHeader == NULL) |
| | | { |
| | | g_pLog->DisplayMessage(_T("%s Full Image Memory Copy fail : Start[%d]-End[%d]"),PANEL_SIDE[eDim],nStartLine,nEndLine); |
| | | LPBYTE lpHeader = m_pGrabber->GetFrameHeaderLine(iScan, nStartLine); |
| | | if (lpHeader == NULL) { |
| | | cLock.Unlock(); |
| | | g_pLog->DisplayMessage(_T("%s Full Image Memory Copy fail : Start[%d]-End[%d]"), PANEL_SIDE[eDim], nStartLine, nEndLine); |
| | | return; |
| | | } |
| | | |
| | | CopyMemory(pImgBuf->pImage,lpHeader,sizeof(BYTE)*pImgBuf->szImage.cx*pImgBuf->szImage.cy); |
| | | CopyMemory(pImgBuf->pImage, lpHeader, sizeof(BYTE) * pImgBuf->szImage.cx * pImgBuf->szImage.cy); |
| | | |
| | | cLock.Unlock(); |
| | | |
| | | g_pLog->DisplayMessage(_T("%s Full Image Memory Copy complete : Start[%d]-End[%d]"),PANEL_SIDE[eDim],nStartLine,nEndLine); |
| | | g_pLog->DisplayMessage(_T("%s Full Image Memory Copy complete : Start[%d]-End[%d]"), PANEL_SIDE[eDim], nStartLine, nEndLine); |
| | | } |
| | | |
| | | |
| | | BOOL CInspectCamera::CheckProcessEnd(int iThread, stFrameIndex stFrame) |
| | | { |
| | | if(m_pGlassData == NULL) |
| | | if (m_pGlassData == NULL) |
| | | return FALSE; |
| | | if(m_pGrabber == NULL) |
| | | return FALSE; |
| | | if (m_pGrabber == NULL) |
| | | return FALSE; |
| | | |
| | | CSide_Data* pSideData = m_pGlassData->GetSideData(GetDimension(stFrame.nScanIdx)); |
| | | if(pSideData == NULL) |
| | | if (pSideData == NULL) |
| | | return FALSE; |
| | | |
| | | if(g_pStatus->GetGrabFrameCount(stFrame.nScanIdx)-1 <= stFrame.nFrameIdx) |
| | | if (g_pStatus->GetGrabFrameCount(stFrame.nScanIdx) - 1 <= stFrame.nFrameIdx) |
| | | return TRUE; |
| | | |
| | | if(pSideData->m_nPreGlassEndFrame+MAX_THREAD <= stFrame.nFrameIdx) |
| | | return TRUE; |
| | | if (pSideData->m_nPreGlassEndFrame + MAX_THREAD <= stFrame.nFrameIdx) |
| | | return TRUE; |
| | | |
| | | // Glass End Line阑 茫绰 Thread 鳖瘤 柳青 吝捞搁 促 场抄芭瘤.. |
| | | if(pSideData->m_bFindGlassEndLine == TRUE || pSideData->GetFrameProc(pSideData->m_nPreGlassEndFrame) == TRUE) |
| | | // Glass End Line을 찾는 Thread 까지 진행 중이면 다 끝난거지.. |
| | | if (pSideData->m_bFindGlassEndLine == TRUE || pSideData->GetFrameProc(pSideData->m_nPreGlassEndFrame) == TRUE) |
| | | return TRUE; |
| | | |
| | | return FALSE; |
| | |
| | | SetGrabEnd(stFrame.nScanIdx); |
| | | } |
| | | |
| | | BOOL CInspectCamera::CheckStartLineFrame(DimensionDir eDim,int iFrame) |
| | | BOOL CInspectCamera::CheckStartLineFrame(DimensionDir eDim, int iFrame) |
| | | { |
| | | CSide_Data* pSideData = m_pGlassData->GetSideData(eDim); |
| | | if(pSideData == NULL) |
| | | if (pSideData == NULL) |
| | | return FALSE; |
| | | |
| | | if(pSideData->m_nGlassStartFrame > iFrame) |
| | | if (pSideData->m_nGlassStartFrame > iFrame) |
| | | return FALSE; |
| | | |
| | | return TRUE; |
| | | } |
| | | |
| | | int CInspectCamera::GetLeftMargin(int iCam,int iScan) |
| | | int CInspectCamera::GetLeftMargin(int iCam, int iScan) |
| | | { |
| | | CCameraSettings *pCamera = m_pHardparm->GetCameraSettings(iCam,iScan); |
| | | if(pCamera == NULL) |
| | | return 0; |
| | | CCameraSettings* pCamera = m_pHardparm->GetCameraSettings(iCam, iScan); |
| | | if (pCamera == NULL) |
| | | return 0; |
| | | |
| | | return pCamera->m_nMarginLeft; |
| | | } |
| | | |
| | | void CInspectCamera::GetFrameSize(int iCam,int iScan,int &nFrameWidth,int &nFrameHeight) |
| | | void CInspectCamera::GetFrameSize(int iCam, int iScan, int& nFrameWidth, int& nFrameHeight) |
| | | { |
| | | nFrameWidth = nFrameHeight = 0; |
| | | |
| | | CCameraSettings *pCamera = m_pHardparm->GetCameraSettings(iCam,iScan); |
| | | if(pCamera == NULL) |
| | | return; |
| | | CCameraSettings* pCamera = m_pHardparm->GetCameraSettings(iCam, iScan); |
| | | if (pCamera == NULL) |
| | | return; |
| | | |
| | | nFrameWidth = pCamera->m_FrameSize.cx; |
| | | nFrameHeight = pCamera->m_FrameSize.cy; |
| | | } |
| | | |
| | | BOOL CInspectCamera::FindEndLine(int iThread,DimensionDir emDim,stFrameIndex stFrame) |
| | | BOOL CInspectCamera::FindEndLine(int iThread, DimensionDir emDim, stFrameIndex stFrame) |
| | | { |
| | | CSide_Data* pSideData = m_pGlassData->GetSideData(emDim); |
| | | if(pSideData == NULL) |
| | | if (pSideData == NULL) |
| | | return FALSE; |
| | | |
| | | if(pSideData->m_nPreGlassEndFrame != stFrame.nFrameIdx) |
| | | if (pSideData->m_nPreGlassEndFrame != stFrame.nFrameIdx) |
| | | return FALSE; |
| | | |
| | | m_MsgJob.nState = 1; |
| | | m_MsgJob.nSide = (int)emDim; |
| | | ::SendMessage(m_hWndViewScan, WM_POCESS_STATUS,(WPARAM)&m_MsgJob, (int)emDim); |
| | | ::SendMessage(m_hWndViewScan, WM_POCESS_STATUS, (WPARAM)&m_MsgJob, (int)emDim); |
| | | |
| | | #define BOUNDARY_GLASSSTARTWIDTH_ENDLINE 140 |
| | | #define BOUNDARYHORIZ_LEVELDIST_ENDLINE 50 // 荐乞 版拌急阑 茫阑 锭狼 厚背芭府 |
| | | #define BOUNDARYHORIZ_LEVELDIST_ENDLINE 50 // 수평 경계선을 찾을 때의 비교거리 |
| | | |
| | | int nFrameWidth = m_nFrameWidth; |
| | | int nFrameHeight = m_nFrameHeight; |
| | | int nThreshold = m_pRecipe->m_SideParam[emDim].m_nFindStartEndLine_Threshold * BOUNDARY_GLASSSTARTWIDTH_ENDLINE; |
| | | int nFrameWidth = m_nFrameWidth; |
| | | int nFrameHeight = m_nFrameHeight; |
| | | int nThreshold = m_pRecipe->m_SideParam[emDim].m_nFindStartEndLine_Threshold * BOUNDARY_GLASSSTARTWIDTH_ENDLINE; |
| | | int nCountinueCount = 0; |
| | | int nHStart, nGab; |
| | | BOOL bContinue = FALSE; |
| | | int nDivHor = 0; |
| | | int iScan = stFrame.nScanIdx; |
| | | BOOL bContinue = FALSE; |
| | | int nDivHor = 0; |
| | | int iScan = stFrame.nScanIdx; |
| | | |
| | | int nSetHor = m_pRecipe->m_SideParam[(int) emDim].m_nFindStartEndLine_X_pxl; |
| | | |
| | | if(nSetHor < BOUNDARY_GLASSSTARTWIDTH_ENDLINE / 2) nSetHor = BOUNDARY_GLASSSTARTWIDTH_ENDLINE / 2; |
| | | if(nSetHor > nFrameWidth-(BOUNDARY_GLASSSTARTWIDTH_ENDLINE / 2)) nSetHor = nFrameWidth-(BOUNDARY_GLASSSTARTWIDTH_ENDLINE / 2); |
| | | int nSetHor = m_pRecipe->m_SideParam[(int)emDim].m_nFindStartEndLine_X_pxl; |
| | | |
| | | g_pLog->DisplayMessage(_T( "%s End Edge Find position Frame[%d],Hor[%d]"),PANEL_SIDE[emDim],stFrame.nFrameIdx,nSetHor); |
| | | if (nSetHor < BOUNDARY_GLASSSTARTWIDTH_ENDLINE / 2) nSetHor = BOUNDARY_GLASSSTARTWIDTH_ENDLINE / 2; |
| | | if (nSetHor > nFrameWidth - (BOUNDARY_GLASSSTARTWIDTH_ENDLINE / 2)) nSetHor = nFrameWidth - (BOUNDARY_GLASSSTARTWIDTH_ENDLINE / 2); |
| | | |
| | | nHStart = nSetHor - BOUNDARY_GLASSSTARTWIDTH_ENDLINE / 2; |
| | | g_pLog->DisplayMessage(_T("%s End Edge Find position Frame[%d],Hor[%d]"), PANEL_SIDE[emDim], stFrame.nFrameIdx, nSetHor); |
| | | |
| | | nHStart = nSetHor - BOUNDARY_GLASSSTARTWIDTH_ENDLINE / 2; |
| | | |
| | | const int nCalculateFrame = 3; |
| | | int nStartFrame = stFrame.nFrameIdx - 2; |
| | | int nVTop = nStartFrame*nFrameHeight; |
| | | LPBYTE lpHeader = m_pGrabber->GetFrameHeaderLine(stFrame.nScanIdx,nVTop); |
| | | int nVTop = nStartFrame * nFrameHeight; |
| | | LPBYTE lpHeader = m_pGrabber->GetFrameHeaderLine(stFrame.nScanIdx, nVTop); |
| | | |
| | | CSISBuffer pVertBuffer(lpHeader,nFrameWidth,nCalculateFrame*nFrameHeight); |
| | | CSISBuffer pVertBuffer(lpHeader, nFrameWidth, nCalculateFrame * nFrameHeight); |
| | | |
| | | if(lpHeader == NULL || pVertBuffer.IsValidBuffer() == FALSE) |
| | | if (lpHeader == NULL || pVertBuffer.IsValidBuffer() == FALSE) |
| | | return FALSE; |
| | | |
| | | int* pnSum = new int[nFrameHeight*nCalculateFrame + BOUNDARYHORIZ_LEVELDIST_ENDLINE]; |
| | | int* pnSum = new int[nFrameHeight * nCalculateFrame + BOUNDARYHORIZ_LEVELDIST_ENDLINE]; |
| | | |
| | | ZeroMemory(pnSum, sizeof(int) * (nFrameHeight*nCalculateFrame + BOUNDARYHORIZ_LEVELDIST_ENDLINE)); |
| | | ZeroMemory(pnSum, sizeof(int) * (nFrameHeight * nCalculateFrame + BOUNDARYHORIZ_LEVELDIST_ENDLINE)); |
| | | |
| | | #ifdef _DEBUG |
| | | CString str; |
| | | str.Format(_T("D:\\InspectionData\\Debug\\Side_%d_EndLineSearch.bmp"),(int)emDim); |
| | | str.Format(_T("D:\\InspectionData\\Debug\\Side_%d_EndLineSearch.bmp"), (int)emDim); |
| | | CBufferAttach saveImage(str); |
| | | saveImage.AttachToFile(pVertBuffer); |
| | | #endif |
| | | |
| | | for (int j = pVertBuffer.GetHeight()-1 ; j >= 0; j--) |
| | | for (int j = pVertBuffer.GetHeight() - 1; j >= 0; j--) |
| | | { |
| | | for (int k = nHStart; k < nHStart+BOUNDARY_GLASSSTARTWIDTH_ENDLINE; k++) |
| | | for (int k = nHStart; k < nHStart + BOUNDARY_GLASSSTARTWIDTH_ENDLINE; k++) |
| | | { |
| | | pnSum[j] += *pVertBuffer.GetDataAddress(k,j); |
| | | } |
| | | pnSum[j] += *pVertBuffer.GetDataAddress(k, j); |
| | | } |
| | | |
| | | if (j <= (pVertBuffer.GetHeight()-1-BOUNDARYHORIZ_LEVELDIST_ENDLINE)) |
| | | if (j <= (pVertBuffer.GetHeight() - 1 - BOUNDARYHORIZ_LEVELDIST_ENDLINE)) |
| | | { |
| | | if(pnSum[j + BOUNDARYHORIZ_LEVELDIST_ENDLINE] == 0 || pnSum[j] == 0) // 肋 给 等 捞固瘤.. |
| | | if (pnSum[j + BOUNDARYHORIZ_LEVELDIST_ENDLINE] == 0 || pnSum[j] == 0) // 잘 못 된 이미지.. |
| | | continue; |
| | | |
| | | nGab = abs(pnSum[j + BOUNDARYHORIZ_LEVELDIST_ENDLINE] - pnSum[j]); |
| | | nGab = abs(pnSum[j + BOUNDARYHORIZ_LEVELDIST_ENDLINE] - pnSum[j]); |
| | | if (nGab > nThreshold) |
| | | nCountinueCount++; |
| | | else |
| | |
| | | |
| | | if (nCountinueCount >= 2) |
| | | { |
| | | // Glass狼 矫累瘤痢阑 茫酒辑 备炼眉俊 持绰促. |
| | | pSideData->m_nGlassEndLine = nStartFrame*nFrameHeight + j + 2; |
| | | pSideData->m_nGlassEndFrame = pSideData->m_nGlassEndLine/nFrameHeight; |
| | | pSideData->m_bFindGlassEndLine = TRUE; |
| | | // Glass의 시작지점을 찾아서 구조체에 넣는다. |
| | | pSideData->m_nGlassEndLine = nStartFrame * nFrameHeight + j + 2; |
| | | pSideData->m_nGlassEndFrame = pSideData->m_nGlassEndLine / nFrameHeight; |
| | | pSideData->m_bFindGlassEndLine = TRUE; |
| | | // pSideData->m_nGlassEdgeXPos[1] = nSetHor; |
| | | |
| | | g_pLog->DisplayMessage(_T( "%s End Line Frame %d, Line %d"), PANEL_SIDE[emDim], pSideData->m_nGlassEndFrame, pSideData->m_nGlassEndLine); |
| | | g_pLog->DisplayMessage(_T("%s End Line Frame %d, Line %d"), PANEL_SIDE[emDim], pSideData->m_nGlassEndFrame, pSideData->m_nGlassEndLine); |
| | | |
| | | /* |
| | | // Log |
| | |
| | | , PANEL_SIDE[emDim] |
| | | , pEdgeInfo->nGlassEdgeXPos[1] |
| | | , pEdgeInfo->nGlassEndLine |
| | | , pEdgeInfo->nGlassEndLine / nFrameHeight); |
| | | , pEdgeInfo->nGlassEndLine / nFrameHeight); |
| | | */ |
| | | |
| | | delete [] pnSum; |
| | | |
| | | delete[] pnSum; |
| | | |
| | | // SaveGlassLineImage(stFrame.nScanIdx,pSideData->m_nGlassEndLine,pSideData->m_nGlassEdgeXPos[1],emDim,_T("EndLine")); |
| | | |
| | | return TRUE; |
| | |
| | | pSideData->m_nGlassEndLine = pSideData->m_nPreGlassEndLine; |
| | | pSideData->m_nGlassEndFrame = pSideData->m_nPreGlassEndFrame; |
| | | pSideData->m_bFindGlassEndLine = TRUE; |
| | | delete [] pnSum; |
| | | delete[] pnSum; |
| | | |
| | | g_pLog->DisplayMessage(_T("%s EndLine Frame %d Fail"),PANEL_SIDE[emDim],stFrame.nFrameIdx); |
| | | g_pLog->DisplayMessage(_T("%s EndLine Frame %d Fail"), PANEL_SIDE[emDim], stFrame.nFrameIdx); |
| | | |
| | | return FALSE; |
| | | } |
| | | |
| | | BOOL CInspectCamera::FindSideLine(int iThread,DimensionDir emDim,stFrameIndex stFrame) |
| | | BOOL CInspectCamera::FindSideLine(int iThread, DimensionDir emDim, stFrameIndex stFrame) |
| | | { |
| | | CSide_Data* pSideData = m_pGlassData->GetSideData(emDim); |
| | | if(pSideData == NULL) |
| | | CSide_Data* pSideData = m_pGlassData->GetSideData(emDim); |
| | | if (pSideData == NULL) |
| | | { |
| | | g_pLog->DisplayMessage(_T("Side Line Find Fail - Glass Data or HW Setting Error")); |
| | | return FALSE; |
| | | } |
| | | |
| | | int nFindLine=-1; |
| | | int nFindLine = -1; |
| | | |
| | | int nThres = m_pRecipe->m_SideParam[(int)(emDim)].m_nSideLineThreshold; |
| | | int nTopCornerSizeX_pxl = (int) GetUmToPixel_X(m_pRecipe->m_SideParam[(int)(emDim)].m_nTopCornerSizeX_um); |
| | | int nTopCornerSizeY_pxl = (int) GetUmToPixel_Y(m_pRecipe->m_SideParam[(int)(emDim)].m_nTopCornerSizeY_um); |
| | | int nBotCornerSizeX_pxl = (int) GetUmToPixel_X(m_pRecipe->m_SideParam[(int)(emDim)].m_nBottomCornerSizeX_um); |
| | | int nBotCornerSizeY_pxl = (int) GetUmToPixel_Y(m_pRecipe->m_SideParam[(int)(emDim)].m_nBottomCornerSizeY_um); |
| | | int nThres = m_pRecipe->m_SideParam[(int)(emDim)].m_nSideLineThreshold; |
| | | int nTopCornerSizeX_pxl = (int)GetUmToPixel_X(m_pRecipe->m_SideParam[(int)(emDim)].m_nTopCornerSizeX_um); |
| | | int nTopCornerSizeY_pxl = (int)GetUmToPixel_Y(m_pRecipe->m_SideParam[(int)(emDim)].m_nTopCornerSizeY_um); |
| | | int nBotCornerSizeX_pxl = (int)GetUmToPixel_X(m_pRecipe->m_SideParam[(int)(emDim)].m_nBottomCornerSizeX_um); |
| | | int nBotCornerSizeY_pxl = (int)GetUmToPixel_Y(m_pRecipe->m_SideParam[(int)(emDim)].m_nBottomCornerSizeY_um); |
| | | |
| | | // Make Region |
| | | CSISEdgeFind EdgeFind; |
| | | const int nSearchHeight = 100; |
| | | int nFrameWidth = m_nFrameWidth; |
| | | int nFrameHeight = m_nFrameHeight; |
| | | const int nSearchHeight = 100; |
| | | int nFrameWidth = m_nFrameWidth; |
| | | int nFrameHeight = m_nFrameHeight; |
| | | |
| | | int nFrameYPos = stFrame.nFrameIdx * nFrameHeight; |
| | | |
| | | CRect rtROI = CRect(GetLeftMargin(m_iCamera,stFrame.nScanIdx),0,m_nFrameWidth-1,m_nFrameHeight); |
| | | CRect rtROI = CRect(GetLeftMargin(m_iCamera, stFrame.nScanIdx), 0, m_nFrameWidth - 1, m_nFrameHeight); |
| | | rtROI.OffsetRect(0, nFrameYPos); |
| | | |
| | | int nTopCorner_Bottom = pSideData->m_nGlassStartLine + nTopCornerSizeY_pxl; |
| | | int nBotCorner_Top = (pSideData->m_bFindGlassEndLine == TRUE) ? pSideData->m_nGlassEndLine - nBotCornerSizeY_pxl : pSideData->m_nPreGlassEndLine - nBotCornerSizeY_pxl; |
| | | int nTopCorner_Bottom = pSideData->m_nGlassStartLine + nTopCornerSizeY_pxl; |
| | | int nBotCorner_Top = (pSideData->m_bFindGlassEndLine == TRUE) ? pSideData->m_nGlassEndLine - nBotCornerSizeY_pxl : pSideData->m_nPreGlassEndLine - nBotCornerSizeY_pxl; |
| | | |
| | | int nTopCorner_Bottom_Frame = nTopCorner_Bottom / nFrameHeight; |
| | | int nBotCorner_Top_Frame = nBotCorner_Top / nFrameHeight; |
| | | |
| | | int nYPos_pxl = 0; |
| | | |
| | | if(nTopCorner_Bottom_Frame == stFrame.nFrameIdx) |
| | | if (nTopCorner_Bottom_Frame == stFrame.nFrameIdx) |
| | | { |
| | | rtROI.top = (rtROI.top < nTopCorner_Bottom) ? nTopCorner_Bottom : rtROI.top; |
| | | nYPos_pxl = rtROI.top; |
| | | rtROI.OffsetRect(0, -nFrameYPos); |
| | | } |
| | | else if(nBotCorner_Top_Frame == stFrame.nFrameIdx) |
| | | else if (nBotCorner_Top_Frame == stFrame.nFrameIdx) |
| | | { |
| | | rtROI.bottom = (nBotCorner_Top_Frame < rtROI.bottom) ? nBotCorner_Top : rtROI.bottom; |
| | | |
| | | // Frame gap.. |
| | | if(rtROI.Height() < m_nFrameHeight/3) |
| | | if (rtROI.Height() < m_nFrameHeight / 3) |
| | | { |
| | | int nExtraArea = m_nFrameHeight - rtROI.Height(); |
| | | int nOffSetY = nFrameYPos - nExtraArea; |
| | |
| | | rtROI.OffsetRect(0, -nFrameYPos); |
| | | } |
| | | |
| | | if(nSearchHeight < rtROI.Height()) |
| | | if (nSearchHeight < rtROI.Height()) |
| | | { |
| | | rtROI.top = rtROI.CenterPoint().y - nSearchHeight/2; |
| | | rtROI.top = rtROI.CenterPoint().y - nSearchHeight / 2; |
| | | rtROI.bottom = rtROI.top + nSearchHeight; |
| | | } |
| | | |
| | | if(rtROI.left < 0) rtROI.left = 0; |
| | | if(rtROI.right >= m_nFrameWidth) rtROI.right = m_nFrameWidth-1; |
| | | if(rtROI.top < 0) rtROI.top = 0; |
| | | if(rtROI.bottom >= m_nFrameHeight) rtROI.bottom = m_nFrameHeight-1; |
| | | if (rtROI.left < 0) rtROI.left = 0; |
| | | if (rtROI.right >= m_nFrameWidth) rtROI.right = m_nFrameWidth - 1; |
| | | if (rtROI.top < 0) rtROI.top = 0; |
| | | if (rtROI.bottom >= m_nFrameHeight) rtROI.bottom = m_nFrameHeight - 1; |
| | | |
| | | // Find Side Line |
| | | #define DEFECT_EDGE_AUTO_RATIO 0.3 |
| | | #define DEFECT_EDGE_AUTO_PITCH 20 |
| | | #define DEFECT_EDGE_CONTINUE 3 |
| | | |
| | | CSISBuffer frameBuffer(m_pGrabber->GetFrameHeaderLine(stFrame.nScanIdx, nYPos_pxl),nFrameWidth,nFrameHeight); |
| | | if(frameBuffer.IsValidBuffer() == FALSE) |
| | | CSISBuffer frameBuffer(m_pGrabber->GetFrameHeaderLine(stFrame.nScanIdx, nYPos_pxl), nFrameWidth, nFrameHeight); |
| | | if (frameBuffer.IsValidBuffer() == FALSE) |
| | | return nFindLine; |
| | | |
| | | EdgeFind.FindEdge_ToRightROI(&frameBuffer,nFindLine,DEFECT_EDGE_AUTO_PITCH,nThres,DEFECT_EDGE_AUTO_RATIO,0,rtROI); |
| | | |
| | | if(nFindLine > 0 && nFindLine < frameBuffer.GetWidth()) |
| | | EdgeFind.FindEdge_ToRightROI(&frameBuffer, nFindLine, DEFECT_EDGE_AUTO_PITCH, nThres, DEFECT_EDGE_AUTO_RATIO, 0, rtROI); |
| | | |
| | | if (nFindLine > 0 && nFindLine < frameBuffer.GetWidth()) |
| | | { |
| | | m_iSideLine[stFrame.nScanIdx] = nFindLine; |
| | | m_iSideLine[stFrame.nScanIdx] = nFindLine; |
| | | |
| | | pSideData->m_nSideLineFrame[stFrame.nFrameIdx] = nFindLine; |
| | | pSideData->m_nSideLinePosY[stFrame.nFrameIdx] = rtROI.CenterPoint().y + nFrameYPos; |
| | | |
| | | // Side 茫绊, Chamfer 茫绰芭 眠啊 鞘夸... |
| | | // Side 찾고, Chamfer 찾는거 추가 필요... |
| | | pSideData->m_nSide_Chamfer_LineFrame[stFrame.nFrameIdx] = nFindLine + 0; |
| | | |
| | | g_pLog->DisplayMessage(_T("Find Side Line Frame[%d], Side[%d]"), stFrame.nFrameIdx, nFindLine); |
| | |
| | | return TRUE; |
| | | } |
| | | |
| | | BOOL CInspectCamera::FindSideLine_ExceptNotch(int iThread,DimensionDir emDim, stFrameIndex stFrame) |
| | | BOOL CInspectCamera::FindSideLine_ExceptNotch(int iThread, DimensionDir emDim, stFrameIndex stFrame) |
| | | { |
| | | CSide_Data* pSideData = m_pGlassData->GetSideData(emDim); |
| | | CSide_Data* pSideData = m_pGlassData->GetSideData(emDim); |
| | | |
| | | if(pSideData == NULL) |
| | | { |
| | | if (pSideData == NULL) { |
| | | g_pLog->DisplayMessage(_T("Side Line Find Fail - Glass Data or HW Setting Error")); |
| | | return FALSE; |
| | | } |
| | | |
| | | int nThres = m_pRecipe->m_SideParam[(int)(emDim)].m_nSideLineThreshold; |
| | | int nTopCornerSizeX_pxl = (int) GetUmToPixel_X(m_pRecipe->m_SideParam[(int)(emDim)].m_nTopCornerSizeX_um); |
| | | int nTopCornerSizeY_pxl = (int) GetUmToPixel_Y(m_pRecipe->m_SideParam[(int)(emDim)].m_nTopCornerSizeY_um); |
| | | int nBotCornerSizeX_pxl = (int) GetUmToPixel_X(m_pRecipe->m_SideParam[(int)(emDim)].m_nBottomCornerSizeX_um); |
| | | int nBotCornerSizeY_pxl = (int) GetUmToPixel_Y(m_pRecipe->m_SideParam[(int)(emDim)].m_nBottomCornerSizeY_um); |
| | | int nThres = m_pRecipe->m_SideParam[(int)(emDim)].m_nSideLineThreshold; |
| | | int nTopCornerSizeX_pxl = (int)GetUmToPixel_X(m_pRecipe->m_SideParam[(int)(emDim)].m_nTopCornerSizeX_um); |
| | | int nTopCornerSizeY_pxl = (int)GetUmToPixel_Y(m_pRecipe->m_SideParam[(int)(emDim)].m_nTopCornerSizeY_um); |
| | | int nBotCornerSizeX_pxl = (int)GetUmToPixel_X(m_pRecipe->m_SideParam[(int)(emDim)].m_nBottomCornerSizeX_um); |
| | | int nBotCornerSizeY_pxl = (int)GetUmToPixel_Y(m_pRecipe->m_SideParam[(int)(emDim)].m_nBottomCornerSizeY_um); |
| | | |
| | | // Make Region |
| | | CSISEdgeFind EdgeFind; |
| | | const int nSearchHeight = 50; |
| | | int nFrameWidth = m_nFrameWidth; |
| | | int nFrameHeight = m_nFrameHeight; |
| | | const int nSearchHeight = 50; |
| | | int nFrameWidth = m_nFrameWidth; |
| | | int nFrameHeight = m_nFrameHeight; |
| | | |
| | | int nFrameYPos = stFrame.nFrameIdx * nFrameHeight; |
| | | |
| | | int nTopCorner_Bottom = pSideData->m_nGlassStartLine + nTopCornerSizeY_pxl; |
| | | int nBotCorner_Top = (pSideData->m_bFindGlassEndLine == TRUE) ? pSideData->m_nGlassEndLine - nBotCornerSizeY_pxl : pSideData->m_nPreGlassEndLine - nBotCornerSizeY_pxl; |
| | | int nTopCorner_Bottom = pSideData->m_nGlassStartLine + nTopCornerSizeY_pxl; |
| | | int nBotCorner_Top = (pSideData->m_bFindGlassEndLine == TRUE) ? pSideData->m_nGlassEndLine - nBotCornerSizeY_pxl : pSideData->m_nPreGlassEndLine - nBotCornerSizeY_pxl; |
| | | |
| | | int nTopCorner_Bottom_Frame = nTopCorner_Bottom / nFrameHeight; |
| | | int nBotCorner_Top_Frame = nBotCorner_Top / nFrameHeight; |
| | |
| | | CRect rtAllSide_pxl; |
| | | rtAllSide_pxl.left = 0; |
| | | rtAllSide_pxl.top = nTopCorner_Bottom; |
| | | rtAllSide_pxl.right = nFrameWidth-1; |
| | | rtAllSide_pxl.right = nFrameWidth - 1; |
| | | rtAllSide_pxl.bottom = nBotCorner_Top; |
| | | |
| | | // 2. Make Frame Area |
| | | CRect rtFrame_pxl = CRect(GetLeftMargin(m_iCamera,stFrame.nScanIdx),0,m_nFrameWidth-1,m_nFrameHeight); |
| | | CRect rtFrame_pxl = CRect(GetLeftMargin(m_iCamera, stFrame.nScanIdx), 0, m_nFrameWidth - 1, m_nFrameHeight); |
| | | rtFrame_pxl.OffsetRect(0, nFrameYPos); |
| | | |
| | | // 3. Make Find Side Line Area. |
| | | CRect rtROI; |
| | | rtROI.IntersectRect(rtFrame_pxl, rtAllSide_pxl); |
| | | |
| | | if(rtROI.IsRectEmpty() || rtROI.IsRectNull()) |
| | | if (rtROI.IsRectEmpty() || rtROI.IsRectNull()) { |
| | | return FALSE; |
| | | } |
| | | |
| | | // 4. Exception Notch Area... |
| | | std::vector<CRect> vectorInspectAreaList_New; |
| | |
| | | |
| | | std::vector<CRect> vecInspectArea; |
| | | |
| | | for(int i=0; i<nNotchCount; i++) |
| | | { |
| | | for (int i = 0; i < nNotchCount; i++) { |
| | | CRect rtNotchArea = pSideData->m_rtNotchArea_pxl[i]; |
| | | rtNotchArea.left = GetLeftMargin(m_iCamera,stFrame.nScanIdx); |
| | | rtNotchArea.right = m_nFrameWidth-1; |
| | | rtNotchArea.left = GetLeftMargin(m_iCamera, stFrame.nScanIdx); |
| | | rtNotchArea.right = m_nFrameWidth - 1; |
| | | |
| | | vectorInspectAreaList_Old.resize(vectorInspectAreaList_New.size()); |
| | | std::copy(vectorInspectAreaList_New.begin(), vectorInspectAreaList_New.end(), vectorInspectAreaList_Old.begin()); |
| | | std::copy(vectorInspectAreaList_New.begin(), vectorInspectAreaList_New.end(), vectorInspectAreaList_Old.begin()); |
| | | vectorInspectAreaList_New.clear(); |
| | | |
| | | for(int j=0; j<vectorInspectAreaList_Old.size(); j++) |
| | | { |
| | | for (int j = 0; j < vectorInspectAreaList_Old.size(); j++) { |
| | | CRect rtTemp = vectorInspectAreaList_Old[j]; |
| | | |
| | | CRect rtNotchInterSectRect; |
| | | rtNotchInterSectRect.IntersectRect(rtTemp, rtNotchArea); |
| | | rtNotchInterSectRect.IntersectRect(rtTemp, rtNotchArea); |
| | | |
| | | if(rtNotchInterSectRect.IsRectEmpty() || rtNotchInterSectRect.IsRectNull()) // 畴摹啊 救吧府绰 版快俊绰 促矫 持绢霖促.. |
| | | { |
| | | if (rtNotchInterSectRect.IsRectEmpty() || rtNotchInterSectRect.IsRectNull()) { |
| | | vectorInspectAreaList_New.push_back(rtTemp); |
| | | continue; |
| | | } |
| | | |
| | | if(rtTemp.Height() == rtNotchInterSectRect.Height()) // Notch啊 康开狼 傈眉牢 版快 |
| | | if (rtTemp.Height() == rtNotchInterSectRect.Height()) { |
| | | continue; |
| | | } |
| | | |
| | | if(rtTemp.top == rtNotchInterSectRect.top && rtNotchInterSectRect.bottom < rtTemp.bottom) // 1. Notch Frame 困俊 吧赴 版快 |
| | | { |
| | | if (rtTemp.top == rtNotchInterSectRect.top && rtNotchInterSectRect.bottom < rtTemp.bottom) { |
| | | CRect rtNew = rtTemp; |
| | | rtNew.top = rtNotchInterSectRect.bottom; |
| | | vectorInspectAreaList_New.push_back(rtNew); |
| | | } |
| | | else if(rtTemp.top < rtNotchInterSectRect.top && rtNotchInterSectRect.bottom < rtTemp.bottom) // 2. Notch Frame 吝埃俊 吧赴 版快 |
| | | { |
| | | else if (rtTemp.top < rtNotchInterSectRect.top && rtNotchInterSectRect.bottom < rtTemp.bottom) { |
| | | CRect rtNewTop = rtTemp; |
| | | rtNewTop.top = rtNotchInterSectRect.bottom; |
| | | vectorInspectAreaList_New.push_back(rtNewTop); |
| | |
| | | rtNewBot.bottom = rtNotchInterSectRect.top; |
| | | vectorInspectAreaList_New.push_back(rtNewBot); |
| | | } |
| | | else if(rtTemp.top < rtNotchInterSectRect.top && rtNotchInterSectRect.bottom == rtTemp.bottom) // 3. Notch Frame 酒贰俊 吧赴 版快 |
| | | { |
| | | else if (rtTemp.top < rtNotchInterSectRect.top && rtNotchInterSectRect.bottom == rtTemp.bottom) { |
| | | CRect rtNew = rtTemp; |
| | | rtNew.bottom = rtNotchInterSectRect.top; |
| | | vectorInspectAreaList_New.push_back(rtNew); |
| | |
| | | } |
| | | } |
| | | |
| | | |
| | | // 5. Side List.. |
| | | vecInspectArea.clear(); |
| | | |
| | | for(int i=0; i<vectorInspectAreaList_New.size(); i++) |
| | | { |
| | | for (int i = 0; i < vectorInspectAreaList_New.size(); i++) { |
| | | CRect rtInspectArea = vectorInspectAreaList_New[i]; |
| | | vecInspectArea.push_back(rtInspectArea); |
| | | } |
| | |
| | | #define DEFECT_EDGE_AUTO_RATIO 0.3 |
| | | #define DEFECT_EDGE_AUTO_PITCH 20 |
| | | #define DEFECT_EDGE_CONTINUE 3 |
| | | |
| | | |
| | | int nFindSideLineSum = 0; |
| | | int nFindSideLineCount = 0; |
| | | int nFindSideLineCount = 0; |
| | | int nFindSideChamferLineSum = 0; |
| | | int nFindSideChamferLineCount = 0; |
| | | int nChamferLineThres = m_pRecipe->m_SideParam[(int) emDim].m_nChamferLineThreshold; |
| | | int nChamferLineThres = m_pRecipe->m_SideParam[(int)emDim].m_nChamferLineThreshold; |
| | | |
| | | #if HALCON_VISION_KEY |
| | | CBlSideData *pBlSideData = BlVision_GetVisionRecipe()->getSideData(emDim); |
| | | CBlSideData* pBlSideData = BlVision_GetVisionRecipe()->getSideData(emDim); |
| | | #endif |
| | | |
| | | int stepSide = m_pGrabber->GetFrameBuffer()->GetFrameHeight(); |
| | | for (int i = 0; i < vecInspectArea.size(); i++) { |
| | | CSISBuffer frameBuffer(m_pGrabber->GetFrameHeaderLine(stFrame.nScanIdx, vecInspectArea[i].top), nFrameWidth, vecInspectArea[i].Height()); |
| | | |
| | | for(int i=0; i<vecInspectArea.size(); i++) |
| | | { |
| | | CSISBuffer frameBuffer(m_pGrabber->GetFrameHeaderLine(stFrame.nScanIdx, vecInspectArea[i].top),nFrameWidth,vecInspectArea[i].Height()); |
| | | |
| | | if(frameBuffer.IsValidBuffer() == FALSE) |
| | | if (frameBuffer.IsValidBuffer() == FALSE) { |
| | | continue; |
| | | } |
| | | |
| | | #ifdef _DEBUG |
| | | CString str; |
| | |
| | | CRect rtFindROI = vecInspectArea[i]; |
| | | rtFindROI.OffsetRect(0, -rtFindROI.top); |
| | | |
| | | if(nSearchHeight < rtFindROI.Height()) |
| | | { |
| | | if (nSearchHeight < rtFindROI.Height()) { |
| | | CPoint ptCenter = rtFindROI.CenterPoint(); |
| | | rtFindROI.top = ptCenter.y - (nSearchHeight/2); |
| | | rtFindROI.bottom = ptCenter.y + (nSearchHeight/2); |
| | | rtFindROI.top = ptCenter.y - (nSearchHeight / 2); |
| | | rtFindROI.bottom = ptCenter.y + (nSearchHeight / 2); |
| | | } |
| | | |
| | | int nSideLine = -1; |
| | | EdgeFind.FindEdge_ToRightROI(&frameBuffer,nSideLine,DEFECT_EDGE_AUTO_PITCH,nThres,DEFECT_EDGE_AUTO_RATIO,0,rtFindROI); |
| | | |
| | | if(nSideLine != -1) |
| | | { |
| | | int nSideLine = -1; |
| | | EdgeFind.FindEdge_ToRightROI(&frameBuffer, nSideLine, DEFECT_EDGE_AUTO_PITCH, nThres, DEFECT_EDGE_AUTO_RATIO, 0, rtFindROI); |
| | | |
| | | if (nSideLine != -1) { |
| | | #if HALCON_VISION_KEY |
| | | if (NULL != pBlSideData){ |
| | | if (NULL != pBlSideData) { |
| | | SideLineInf inf; |
| | | inf.left = 0; |
| | | inf.top = vecInspectArea[i].top; |
| | |
| | | int idx = (int)(vecInspectArea[i].top / stepSide); |
| | | pBlSideData->m_mapSideLineInf[idx] = inf; |
| | | |
| | | //打印边界数据 |
| | | //댔丹긋썹鑒앴 |
| | | //Log_GetDebug()->TraceInfo("Find Side Line %d: %d, %d, (%d, %d, %d, %d), %d", |
| | | // idx, |
| | | // inf.nSideLine, inf.nThres, |
| | |
| | | CChamferInspect chamferIns; |
| | | double dLine = -1; |
| | | |
| | | COwnerBuffer ImgInsBin; |
| | | chamferIns.Binarization(frameBuffer,ImgInsBin,nChamferLineThres); |
| | | COwnerBuffer ImgInsBin; |
| | | chamferIns.Binarization(frameBuffer, ImgInsBin, nChamferLineThres); |
| | | |
| | | chamferIns.FindRightLine_Bin(ImgInsBin,nSideLine,dLine); |
| | | if(dLine != -1) |
| | | { |
| | | chamferIns.FindRightLine_Bin(ImgInsBin, nSideLine, dLine); |
| | | if (dLine != -1) { |
| | | nFindSideChamferLineSum += (int)dLine; |
| | | nFindSideChamferLineCount++; |
| | | } |
| | | } |
| | | } |
| | | |
| | | if(nFindSideLineCount > 0) |
| | | { |
| | | int nAvgSideLine = (int) (nFindSideLineSum / nFindSideLineCount); // Average.. |
| | | if (nFindSideLineCount > 0) { |
| | | int nAvgSideLine = (int)(nFindSideLineSum / nFindSideLineCount); |
| | | m_iSideLine[stFrame.nScanIdx] = nAvgSideLine; |
| | | pSideData->m_nSideLineFrame[stFrame.nFrameIdx] = nAvgSideLine; |
| | | pSideData->m_nSideLineFrame[stFrame.nFrameIdx] = nAvgSideLine; |
| | | pSideData->m_nSideLinePosY[stFrame.nFrameIdx] = rtROI.CenterPoint().y + nFrameYPos; |
| | | } |
| | | |
| | | if(nFindSideChamferLineCount > 0) |
| | | { |
| | | int nAvgChamferLine = (int) (nFindSideChamferLineSum / nFindSideChamferLineCount); // Average.. |
| | | pSideData->m_nSide_Chamfer_LineFrame[stFrame.nFrameIdx] = nAvgChamferLine; // Chamfer Line |
| | | if (nFindSideChamferLineCount > 0) { |
| | | int nAvgChamferLine = (int)(nFindSideChamferLineSum / nFindSideChamferLineCount); // Average.. |
| | | pSideData->m_nSide_Chamfer_LineFrame[stFrame.nFrameIdx] = nAvgChamferLine; // Chamfer Line |
| | | } |
| | | |
| | | return TRUE; |
| | | } |
| | | |
| | | BOOL CInspectCamera::FindTopCorner(int iThread,DimensionDir emDim, stFrameIndex stFrame) |
| | | BOOL CInspectCamera::FindTopCorner(int iThread, DimensionDir emDim, stFrameIndex stFrame) |
| | | { |
| | | CSingleLock localLock(&m_csTopCorner); |
| | | localLock.Lock(); |
| | | |
| | | if(m_pGlassData == NULL) |
| | | if (m_pGlassData == NULL) { |
| | | localLock.Unlock(); |
| | | return FALSE; |
| | | } |
| | | |
| | | CSide_Data* pSideData = m_pGlassData->GetSideData(emDim); |
| | | CSIDE_PARM* pSideParam = &m_pRecipe->m_SideParam[(int) emDim]; |
| | | CSIDE_PARM* pSideParam = &m_pRecipe->m_SideParam[(int)emDim]; |
| | | |
| | | if(pSideData == NULL || pSideParam == NULL) |
| | | return FALSE; |
| | | |
| | | if(pSideData->m_bFindGlassStartLine == FALSE) |
| | | if (pSideData == NULL || pSideParam == NULL) { |
| | | localLock.Unlock(); |
| | | return FALSE; |
| | | } |
| | | |
| | | if(pSideData->m_bTopCorner_Find == TRUE) |
| | | if (pSideData->m_bFindGlassStartLine == FALSE) { |
| | | localLock.Unlock(); |
| | | return FALSE; |
| | | } |
| | | |
| | | if (pSideData->m_bTopCorner_Find == TRUE) { |
| | | localLock.Unlock(); |
| | | return TRUE; |
| | | } |
| | | |
| | | /* |
| | | BOOL bTopCornerUse = (BOOL) (m_pRecipe->m_SideParam[emDim].m_nTopCornerShape == 0) ? FALSE : TRUE; |
| | | |
| | | // Not Use Corner Inspection |
| | | if(bTopCornerUse == FALSE) |
| | | BOOL bTopCornerUse = (BOOL)(m_pRecipe->m_SideParam[emDim].m_nTopCornerShape == 0) ? FALSE : TRUE; |
| | | if (bTopCornerUse == FALSE) { |
| | | localLock.Unlock(); |
| | | return FALSE; |
| | | */ |
| | | } |
| | | |
| | | double dCornerSizeY_Um = (double) m_pRecipe->m_SideParam[emDim].m_nTopCornerSizeY_um; |
| | | |
| | | int nCornerSizeY_Pixel = (int) GetUmToPixel_Y(dCornerSizeY_Um); |
| | | |
| | | int nFrameHeight = m_nFrameHeight; |
| | | |
| | | int nFindStartLine = pSideData->m_nGlassStartLine; |
| | | |
| | | double dCornerSizeY_Um = (double)m_pRecipe->m_SideParam[emDim].m_nTopCornerSizeY_um; |
| | | int nCornerSizeY_Pixel = (int)GetUmToPixel_Y(dCornerSizeY_Um); |
| | | int nFrameHeight = m_nFrameHeight; |
| | | int nFindStartLine = pSideData->m_nGlassStartLine; |
| | | int nTopCornerFrameIndex = (nFindStartLine + nCornerSizeY_Pixel) / nFrameHeight; |
| | | |
| | | if(stFrame.nFrameIdx < nTopCornerFrameIndex+1) |
| | | if (stFrame.nFrameIdx < nTopCornerFrameIndex + 1) { |
| | | localLock.Unlock(); |
| | | return FALSE; |
| | | } |
| | | |
| | | int nSideLine = pSideData->m_nSideLineFrame[nTopCornerFrameIndex+1]; |
| | | int nSideLine = (int)pSideData->m_nSideLineFrame[nTopCornerFrameIndex + 1]; |
| | | |
| | | if(nSideLine == -1) |
| | | if (nSideLine == -1) { |
| | | localLock.Unlock(); |
| | | return FALSE; |
| | | } |
| | | |
| | | double dCornerSizeX_Um = (double) m_pRecipe->m_SideParam[emDim].m_nTopCornerSizeX_um; |
| | | |
| | | int nCornerSizeX_Pixel = (int) GetUmToPixel_X(dCornerSizeX_Um); |
| | | double dCornerSizeX_Um = (double)m_pRecipe->m_SideParam[emDim].m_nTopCornerSizeX_um; |
| | | int nCornerSizeX_Pixel = (int)GetUmToPixel_X(dCornerSizeX_Um); |
| | | |
| | | CRect rtTopCornerArea(0, 0, nCornerSizeX_Pixel, nCornerSizeY_Pixel); |
| | | |
| | | rtTopCornerArea.OffsetRect(nSideLine, nFindStartLine); |
| | | |
| | | pSideData->m_bTopCorner_Find = TRUE; |
| | |
| | | int nTopCornerType = m_pRecipe->m_SideParam[emDim].m_nTopCornerShape; |
| | | pSideData->m_nTopCornerShape = m_pRecipe->m_SideParam[emDim].m_nTopCornerShape;; |
| | | |
| | | if(pSideParam->m_bTopCornerFindDefect == FALSE) |
| | | if (pSideParam->m_bTopCornerFindDefect == FALSE) { |
| | | localLock.Unlock(); |
| | | return FALSE; |
| | | } |
| | | |
| | | if(nTopCornerType == (int) 1) return FindTopCorner_CCut(iThread, emDim, stFrame); |
| | | else if(nTopCornerType == (int) 2) return FindTopCorner_RCut(iThread, emDim, stFrame); |
| | | localLock.Unlock(); |
| | | |
| | | if (nTopCornerType == (int)1) return FindTopCorner_CCut(iThread, emDim, stFrame); |
| | | else if (nTopCornerType == (int)2) return FindTopCorner_RCut(iThread, emDim, stFrame); |
| | | else return FindTopCorner_None(iThread, emDim, stFrame); |
| | | |
| | | return TRUE; |
| | |
| | | |
| | | BOOL CInspectCamera::FindTopCorner_None(int iThread, DimensionDir emDim, stFrameIndex stFrame) |
| | | { |
| | | if(m_pGlassData == NULL) |
| | | if (m_pGlassData == NULL) |
| | | return FALSE; |
| | | |
| | | CSide_Data* pSideData = m_pGlassData->GetSideData(emDim); |
| | | |
| | | if(pSideData == FALSE) |
| | | if (pSideData == FALSE) |
| | | return FALSE; |
| | | |
| | | CRect rtTopCornerArea = pSideData->m_rtTopCornerArea; |
| | | rtTopCornerArea.right = rtTopCornerArea.left + ALIGN_4BYTE(rtTopCornerArea.Width()); |
| | | |
| | | if(rtTopCornerArea.IsRectEmpty() || rtTopCornerArea.IsRectNull()) |
| | | if (rtTopCornerArea.IsRectEmpty() || rtTopCornerArea.IsRectNull()) |
| | | return FALSE; |
| | | |
| | | int nFrameWidth = m_nFrameWidth; |
| | | int nFrameWidth = m_nFrameWidth; |
| | | |
| | | // 1. Inspect ROI |
| | | COwnerBuffer pBuffer(rtTopCornerArea.Width(), rtTopCornerArea.Height()); |
| | |
| | | |
| | | int nMinSize = m_pRecipe->m_SideParam[emDim].m_nTopCornerIns_Min_Size; |
| | | |
| | | int nDilation = m_pRecipe->m_SideParam[emDim].m_nTopCornerIns_Defect_Size_Dilation; |
| | | int nDilation = m_pRecipe->m_SideParam[emDim].m_nTopCornerIns_Defect_Size_Dilation; |
| | | |
| | | // For Draw.. |
| | | pSideData->m_rtTopCornerArea_Offset = rtTopCornerArea; |
| | |
| | | int nImageX = nInsStart; |
| | | int nImageY = i; |
| | | |
| | | if (nImageX < 0 ||rtTopCornerArea.Width() <= nImageX || nImageY < 0 || rtTopCornerArea.Height() <= nImageY) |
| | | if (nImageX < 0 || rtTopCornerArea.Width() <= nImageX || nImageY < 0 || rtTopCornerArea.Height() <= nImageY) |
| | | continue; |
| | | |
| | | int nRange = (rtTopCornerArea.Width() <= nImageX + nInsRange) ? (rtTopCornerArea.Width() - 1 - nImageX) : nInsRange; |
| | |
| | | return TRUE; |
| | | } |
| | | |
| | | BOOL CInspectCamera::FindTopCorner_CCut(int iThread,DimensionDir emDim, stFrameIndex stFrame) |
| | | BOOL CInspectCamera::FindTopCorner_CCut(int iThread, DimensionDir emDim, stFrameIndex stFrame) |
| | | { |
| | | if(m_pGlassData == NULL) |
| | | if (m_pGlassData == NULL) |
| | | return FALSE; |
| | | |
| | | CSide_Data* pSideData = m_pGlassData->GetSideData(emDim); |
| | | |
| | | if(pSideData == FALSE) |
| | | if (pSideData == FALSE) |
| | | return FALSE; |
| | | |
| | | CRect rtTopCornerArea = pSideData->m_rtTopCornerArea; |
| | | rtTopCornerArea.right = rtTopCornerArea.left + ALIGN_4BYTE(rtTopCornerArea.Width()); |
| | | |
| | | if(rtTopCornerArea.IsRectEmpty() || rtTopCornerArea.IsRectNull()) |
| | | if (rtTopCornerArea.IsRectEmpty() || rtTopCornerArea.IsRectNull()) |
| | | return FALSE; |
| | | |
| | | int nFrameWidth = m_nFrameWidth; |
| | | int nFrameWidth = m_nFrameWidth; |
| | | |
| | | // 1. Inspect ROI |
| | | COwnerBuffer pBuffer(rtTopCornerArea.Width(), rtTopCornerArea.Height()); |
| | |
| | | |
| | | int nMinSize = m_pRecipe->m_SideParam[emDim].m_nTopCornerIns_Min_Size; |
| | | |
| | | int nDilation = m_pRecipe->m_SideParam[emDim].m_nTopCornerIns_Defect_Size_Dilation; |
| | | int nDilation = m_pRecipe->m_SideParam[emDim].m_nTopCornerIns_Defect_Size_Dilation; |
| | | |
| | | // For Draw.. |
| | | pSideData->m_rtTopCornerArea_Offset = rtTopCornerArea; |
| | |
| | | for (int i = 0; i < rtTopCornerArea.Width(); i++) |
| | | { |
| | | int nX = rtTopCornerArea.Width() - 1 - i; |
| | | int nY = (int) (((double)i * dScaleY) + nInsStart); |
| | | int nY = (int)(((double)i * dScaleY) + nInsStart); |
| | | |
| | | if (nX < 0 ||rtTopCornerArea.Width() <= nX || nY < 0 || rtTopCornerArea.Height() <= nY) |
| | | if (nX < 0 || rtTopCornerArea.Width() <= nX || nY < 0 || rtTopCornerArea.Height() <= nY) |
| | | continue; |
| | | |
| | | int nRange = (rtTopCornerArea.Height() <= nY + nInsRange) ? (rtTopCornerArea.Height() - 1 - nY) : nInsRange; |
| | | |
| | | if(nRange == 0) |
| | | if (nRange == 0) |
| | | continue; |
| | | |
| | | for(int j=0; j<nRange; j++) |
| | | pMaskBuffer.SetPixel(nX, nY+j, 255); |
| | | for (int j = 0; j < nRange; j++) |
| | | pMaskBuffer.SetPixel(nX, nY + j, 255); |
| | | |
| | | /* |
| | | int nRange = (rtTopCornerArea.Width() <= nX + nInsRange) ? (rtTopCornerArea.Width() - 1 - nX) : nInsRange; |
| | |
| | | return TRUE; |
| | | } |
| | | |
| | | BOOL CInspectCamera::FindTopCorner_RCut(int iThread,DimensionDir emDim, stFrameIndex stFrame) |
| | | BOOL CInspectCamera::FindTopCorner_RCut(int iThread, DimensionDir emDim, stFrameIndex stFrame) |
| | | { |
| | | if(m_pGlassData == NULL) |
| | | if (m_pGlassData == NULL) |
| | | return FALSE; |
| | | |
| | | CSide_Data* pSideData = m_pGlassData->GetSideData(emDim); |
| | | |
| | | if(pSideData == FALSE) |
| | | if (pSideData == FALSE) |
| | | return FALSE; |
| | | |
| | | CRect rtTopCornerArea = pSideData->m_rtTopCornerArea; |
| | | rtTopCornerArea.right = rtTopCornerArea.left + ALIGN_4BYTE(rtTopCornerArea.Width()); |
| | | |
| | | if(rtTopCornerArea.IsRectEmpty() || rtTopCornerArea.IsRectNull()) |
| | | if (rtTopCornerArea.IsRectEmpty() || rtTopCornerArea.IsRectNull()) |
| | | return FALSE; |
| | | |
| | | int nFrameWidth = m_nFrameWidth; |
| | | int nFrameWidth = m_nFrameWidth; |
| | | |
| | | // 1. Inspect ROI |
| | | COwnerBuffer pBuffer(rtTopCornerArea.Width(), rtTopCornerArea.Height()); |
| | |
| | | return TRUE; |
| | | } |
| | | |
| | | BOOL CInspectCamera::FindTopAlignMark(int iThread,DimensionDir eDim, stFrameIndex stFrame) |
| | | BOOL CInspectCamera::FindTopAlignMark(int iThread, DimensionDir eDim, stFrameIndex stFrame) |
| | | { |
| | | CSingleLock localLock(&m_csThreadTopAlignMark); |
| | | localLock.Lock(); |
| | | |
| | | if(m_pGlassData == NULL) |
| | | if (m_pGlassData == NULL) { |
| | | localLock.Unlock(); |
| | | return FALSE; |
| | | } |
| | | |
| | | CSide_Data* pSideData = m_pGlassData->GetSideData(eDim); |
| | | |
| | | if(pSideData == NULL) |
| | | CSide_Data* pSideData = m_pGlassData->GetSideData(eDim); |
| | | if (pSideData == NULL) { |
| | | localLock.Unlock(); |
| | | return FALSE; |
| | | } |
| | | |
| | | if(pSideData->m_bFindGlassStartLine == FALSE) |
| | | if (pSideData->m_bFindGlassStartLine == FALSE) { |
| | | localLock.Unlock(); |
| | | return FALSE; |
| | | } |
| | | |
| | | if(pSideData->m_bTopMark_Find == TRUE) |
| | | if (pSideData->m_bTopMark_Find == TRUE) { |
| | | localLock.Unlock(); |
| | | return TRUE; |
| | | } |
| | | |
| | | if(pSideData->m_bTopCorner_Find == FALSE) |
| | | return FALSE; |
| | | if (pSideData->m_bTopCorner_Find == FALSE) { |
| | | localLock.Unlock(); |
| | | return FALSE; |
| | | } |
| | | |
| | | BOOL bTopAlignMark = (BOOL) (m_pRecipe->m_SideParam[eDim].m_bTopMark_Use == 1) ? TRUE : FALSE; |
| | | |
| | | if(bTopAlignMark == FALSE) |
| | | BOOL bTopAlignMark = (BOOL)(m_pRecipe->m_SideParam[eDim].m_bTopMark_Use == 1) ? TRUE : FALSE; |
| | | if (bTopAlignMark == FALSE) { |
| | | localLock.Unlock(); |
| | | return FindTopAlignMark_Virtual(iThread, eDim, stFrame); |
| | | else |
| | | { |
| | | if(FindTopAlignMark_TempleteMatching(iThread, eDim, stFrame) == FALSE) |
| | | } |
| | | else { |
| | | if (FindTopAlignMark_TempleteMatching(iThread, eDim, stFrame) == FALSE) { |
| | | localLock.Unlock(); |
| | | return FindTopAlignMark_Virtual(iThread, eDim, stFrame); |
| | | else |
| | | } |
| | | else { |
| | | localLock.Unlock(); |
| | | return TRUE; |
| | | } |
| | | } |
| | | } |
| | | |
| | | BOOL CInspectCamera::FindTopAlignMark_Virtual(int iThread,DimensionDir eDim, stFrameIndex stFrame) |
| | | BOOL CInspectCamera::FindTopAlignMark_Virtual(int iThread, DimensionDir eDim, stFrameIndex stFrame) |
| | | { |
| | | if(m_pGlassData == NULL) |
| | | if (m_pGlassData == NULL) |
| | | return FALSE; |
| | | |
| | | CSide_Data* pSideData = m_pGlassData->GetSideData(eDim); |
| | | CSide_Data* pSideData = m_pGlassData->GetSideData(eDim); |
| | | |
| | | if(pSideData == NULL) |
| | | if (pSideData == NULL) |
| | | return FALSE; |
| | | |
| | | if(pSideData->m_bFindGlassStartLine == FALSE) |
| | | if (pSideData->m_bFindGlassStartLine == FALSE) |
| | | return FALSE; |
| | | |
| | | if(pSideData->m_bTopMark_Find == TRUE) |
| | | if (pSideData->m_bTopMark_Find == TRUE) |
| | | return TRUE; |
| | | |
| | | if(pSideData->m_bTopCorner_Find == FALSE) |
| | | return FALSE; |
| | | |
| | | // 1. Make ROI |
| | | int nFrameWidth = m_nFrameWidth; |
| | | int nFrameHeight = m_nFrameHeight; |
| | | |
| | | int nStartLine = pSideData->m_nGlassStartLine; |
| | | double dEdgeToTopAlignMarkY_Um = m_pRecipe->m_SideParam[eDim].m_nTopMarkToEdgeY_um; |
| | | int nEdgeToTopAlignMarkY_Pixel = (int) GetUmToPixel_Y(dEdgeToTopAlignMarkY_Um); |
| | | int nTopAlignMarkY_Pixel = nStartLine + nEdgeToTopAlignMarkY_Pixel; |
| | | |
| | | int nTopAlignMarkYPramIdx = nTopAlignMarkY_Pixel / nFrameHeight; |
| | | if((int) stFrame.nFrameIdx < nTopAlignMarkYPramIdx + 1) |
| | | if (pSideData->m_bTopCorner_Find == FALSE) |
| | | return FALSE; |
| | | |
| | | int nSideLine = pSideData->m_nSideLineFrame[nTopAlignMarkYPramIdx + 1]; |
| | | double nEdgeToTopAlignMarkX_Um = m_pRecipe->m_SideParam[eDim].m_nTopMarkToEdgeX_um; |
| | | int nEdgeToTopAlignMarkX_Pixel = (int) GetUmToPixel_X(nEdgeToTopAlignMarkX_Um); |
| | | int nTopAlignMarkX_Pixel = nSideLine + nEdgeToTopAlignMarkX_Pixel; |
| | | |
| | | // 1. Make ROI |
| | | int nFrameWidth = m_nFrameWidth; |
| | | int nFrameHeight = m_nFrameHeight; |
| | | |
| | | int nStartLine = pSideData->m_nGlassStartLine; |
| | | double dEdgeToTopAlignMarkY_Um = m_pRecipe->m_SideParam[eDim].m_nTopMarkToEdgeY_um; |
| | | int nEdgeToTopAlignMarkY_Pixel = (int)GetUmToPixel_Y(dEdgeToTopAlignMarkY_Um); |
| | | int nTopAlignMarkY_Pixel = nStartLine + nEdgeToTopAlignMarkY_Pixel; |
| | | |
| | | int nTopAlignMarkYPramIdx = nTopAlignMarkY_Pixel / nFrameHeight; |
| | | if ((int)stFrame.nFrameIdx < nTopAlignMarkYPramIdx + 1) |
| | | return FALSE; |
| | | |
| | | int nSideLine = (int)pSideData->m_nSideLineFrame[nTopAlignMarkYPramIdx + 1]; |
| | | double nEdgeToTopAlignMarkX_Um = m_pRecipe->m_SideParam[eDim].m_nTopMarkToEdgeX_um; |
| | | int nEdgeToTopAlignMarkX_Pixel = (int)GetUmToPixel_X(nEdgeToTopAlignMarkX_Um); |
| | | int nTopAlignMarkX_Pixel = nSideLine + nEdgeToTopAlignMarkX_Pixel; |
| | | |
| | | CRect rtSearchArea = CRect(nTopAlignMarkX_Pixel, nTopAlignMarkY_Pixel, nTopAlignMarkX_Pixel, nTopAlignMarkY_Pixel); |
| | | rtSearchArea.InflateRect(50, 50); |
| | | |
| | |
| | | return TRUE; |
| | | } |
| | | |
| | | BOOL CInspectCamera::FindTopAlignMark_TempleteMatching(int iThread,DimensionDir eDim, stFrameIndex stFrame) |
| | | BOOL CInspectCamera::FindTopAlignMark_TempleteMatching(int iThread, DimensionDir eDim, stFrameIndex stFrame) |
| | | { |
| | | if(m_pGlassData == NULL) |
| | | if (m_pGlassData == NULL) |
| | | return FALSE; |
| | | |
| | | CSide_Data* pSideData = m_pGlassData->GetSideData(eDim); |
| | | CSide_Data* pSideData = m_pGlassData->GetSideData(eDim); |
| | | |
| | | if(pSideData == NULL) |
| | | if (pSideData == NULL) |
| | | return FALSE; |
| | | |
| | | if(pSideData->m_bFindGlassStartLine == FALSE) |
| | | if (pSideData->m_bFindGlassStartLine == FALSE) |
| | | return FALSE; |
| | | |
| | | if(pSideData->m_bTopMark_Find == TRUE) |
| | | if (pSideData->m_bTopMark_Find == TRUE) |
| | | return TRUE; |
| | | |
| | | if(pSideData->m_bTopCorner_Find == FALSE) |
| | | return FALSE; |
| | | if (pSideData->m_bTopCorner_Find == FALSE) |
| | | return FALSE; |
| | | |
| | | // 1. Make ROI |
| | | int nFrameWidth = m_nFrameWidth; |
| | | int nFrameHeight = m_nFrameHeight; |
| | | int nFrameWidth = m_nFrameWidth; |
| | | int nFrameHeight = m_nFrameHeight; |
| | | |
| | | int nStartLine = pSideData->m_nGlassStartLine; |
| | | double dEdgeToTopAlignMarkY_Um = m_pRecipe->m_SideParam[eDim].m_nTopMarkToEdgeY_um; |
| | | int nEdgeToTopAlignMarkY_Pixel = (int) GetUmToPixel_Y(dEdgeToTopAlignMarkY_Um); |
| | | int nTopAlignMarkY_Pixel = nStartLine + nEdgeToTopAlignMarkY_Pixel; |
| | | int nTopAlignMarkYPramIdx = nTopAlignMarkY_Pixel / nFrameHeight; |
| | | int nStartLine = pSideData->m_nGlassStartLine; |
| | | double dEdgeToTopAlignMarkY_Um = m_pRecipe->m_SideParam[eDim].m_nTopMarkToEdgeY_um; |
| | | int nEdgeToTopAlignMarkY_Pixel = (int)GetUmToPixel_Y(dEdgeToTopAlignMarkY_Um); |
| | | int nTopAlignMarkY_Pixel = nStartLine + nEdgeToTopAlignMarkY_Pixel; |
| | | int nTopAlignMarkYPramIdx = nTopAlignMarkY_Pixel / nFrameHeight; |
| | | |
| | | if((int) stFrame.nFrameIdx < nTopAlignMarkYPramIdx + 1) |
| | | return FALSE; |
| | | if ((int)stFrame.nFrameIdx < nTopAlignMarkYPramIdx + 1) |
| | | return FALSE; |
| | | |
| | | int nSideLine = pSideData->m_nSideLineFrame[nTopAlignMarkYPramIdx + 1]; |
| | | int nSideLine = (int)pSideData->m_nSideLineFrame[nTopAlignMarkYPramIdx + 1]; |
| | | |
| | | if(nSideLine <= 0) |
| | | if (nSideLine <= 0) |
| | | { |
| | | CRect rectSide = CRect(0,nTopAlignMarkY_Pixel,nFrameWidth-1,nTopAlignMarkY_Pixel); |
| | | CRect rectSide = CRect(0, nTopAlignMarkY_Pixel, nFrameWidth - 1, nTopAlignMarkY_Pixel); |
| | | |
| | | rectSide.InflateRect(0,30); |
| | | rectSide.InflateRect(0, 30); |
| | | |
| | | CSISBuffer frameBuffer(m_pGrabber->GetFrameHeaderLine(stFrame.nScanIdx, rectSide.top),nFrameWidth,rectSide.Height()); |
| | | CSISBuffer frameBuffer(m_pGrabber->GetFrameHeaderLine(stFrame.nScanIdx, rectSide.top), nFrameWidth, rectSide.Height()); |
| | | |
| | | if(frameBuffer.IsValidBuffer() == FALSE) |
| | | if (frameBuffer.IsValidBuffer() == FALSE) |
| | | return FALSE; |
| | | |
| | | rectSide.OffsetRect(0, -rectSide.top); |
| | | |
| | | int nThres = m_pRecipe->m_SideParam[(int)(eDim)].m_nSideLineThreshold; |
| | | int nThres = m_pRecipe->m_SideParam[(int)(eDim)].m_nSideLineThreshold; |
| | | |
| | | CSISEdgeFind EdgeFind; |
| | | EdgeFind.FindEdge_ToRightROI(&frameBuffer,nSideLine,DEFECT_EDGE_AUTO_PITCH,nThres,DEFECT_EDGE_AUTO_RATIO,0,rectSide); |
| | | EdgeFind.FindEdge_ToRightROI(&frameBuffer, nSideLine, DEFECT_EDGE_AUTO_PITCH, nThres, DEFECT_EDGE_AUTO_RATIO, 0, rectSide); |
| | | } |
| | | |
| | | if(nSideLine <= 0) |
| | | if (nSideLine <= 0) |
| | | return FALSE; |
| | | |
| | | double nEdgeToTopAlignMarkX_Um = m_pRecipe->m_SideParam[eDim].m_nTopMarkToEdgeX_um; |
| | | int nEdgeToTopAlignMarkX_Pixel = (int) GetUmToPixel_X(nEdgeToTopAlignMarkX_Um); |
| | | int nTopAlignMarkX_Pixel = nSideLine + nEdgeToTopAlignMarkX_Pixel; |
| | | double nEdgeToTopAlignMarkX_Um = m_pRecipe->m_SideParam[eDim].m_nTopMarkToEdgeX_um; |
| | | int nEdgeToTopAlignMarkX_Pixel = (int)GetUmToPixel_X(nEdgeToTopAlignMarkX_Um); |
| | | int nTopAlignMarkX_Pixel = nSideLine + nEdgeToTopAlignMarkX_Pixel; |
| | | |
| | | double dTarget_Rate = m_pRecipe->m_SideParam[(int) eDim].m_dTopMarkTemplateMatchingRate / 100.0; |
| | | double dTarget_Rate = m_pRecipe->m_SideParam[(int)eDim].m_dTopMarkTemplateMatchingRate / 100.0; |
| | | |
| | | CvPoint ptMax_Point; |
| | | double dMat_Max_Rate; |
| | |
| | | |
| | | // Make Mark Defect.. |
| | | CDefect_Info defectInfo; |
| | | defectInfo.m_iFrameIdx = stFrame.nFrameIdx; |
| | | defectInfo.m_nCamID = m_iCamera; |
| | | defectInfo.m_nScanIdx = stFrame.nScanIdx; |
| | | defectInfo.m_nGlassStartLine = m_pGlassData->GetSideData(eDim)->m_nGlassStartLine; |
| | | defectInfo.m_nSideIdx = (int) eDim; |
| | | defectInfo.m_ptDefectPos_pxl = pSideData->m_rtTopMark_SearchArea.CenterPoint(); |
| | | defectInfo.m_rtDefectPos_pxl = pSideData->m_rtTopMark_SearchArea; |
| | | defectInfo.m_DefectLoc = DefectLoc_Mark; |
| | | defectInfo.m_iFrameIdx = stFrame.nFrameIdx; |
| | | defectInfo.m_nCamID = m_iCamera; |
| | | defectInfo.m_nScanIdx = stFrame.nScanIdx; |
| | | defectInfo.m_nGlassStartLine = m_pGlassData->GetSideData(eDim)->m_nGlassStartLine; |
| | | defectInfo.m_nSideIdx = (int)eDim; |
| | | defectInfo.m_ptDefectPos_pxl = pSideData->m_rtTopMark_SearchArea.CenterPoint(); |
| | | defectInfo.m_rtDefectPos_pxl = pSideData->m_rtTopMark_SearchArea; |
| | | defectInfo.m_DefectLoc = DefectLoc_Mark; |
| | | |
| | | m_pDefectControl->ExtractDefect_Mark(eDim, m_iCamera, stFrame.nScanIdx, defectInfo); |
| | | |
| | | return FALSE; |
| | | } |
| | | |
| | | BOOL CInspectCamera::FindBotCorner(int iThread,DimensionDir emDim, stFrameIndex stFrame) |
| | | BOOL CInspectCamera::FindBotCorner(int iThread, DimensionDir emDim, stFrameIndex stFrame) |
| | | { |
| | | CSingleLock localLock(&m_csBotCorner); |
| | | localLock.Lock(); |
| | | |
| | | if(m_pGlassData == NULL) |
| | | if (m_pGlassData == NULL) { |
| | | localLock.Unlock(); |
| | | return FALSE; |
| | | } |
| | | |
| | | CSide_Data* pSideData = m_pGlassData->GetSideData(emDim); |
| | | CSIDE_PARM* pSideParam = &m_pRecipe->m_SideParam[(int) emDim]; |
| | | CSIDE_PARM* pSideParam = &m_pRecipe->m_SideParam[(int)emDim]; |
| | | |
| | | if(pSideData == NULL || pSideParam == NULL) |
| | | if (pSideData == NULL || pSideParam == NULL) { |
| | | localLock.Unlock(); |
| | | return FALSE; |
| | | } |
| | | |
| | | if (pSideData->m_bFindGlassStartLine == FALSE || pSideData->m_bFindGlassEndLine == FALSE) |
| | | if (pSideData->m_bFindGlassStartLine == FALSE || pSideData->m_bFindGlassEndLine == FALSE) { |
| | | localLock.Unlock(); |
| | | return FALSE; |
| | | } |
| | | |
| | | if(pSideData->m_bBotCorner_Find == TRUE) |
| | | if (pSideData->m_bBotCorner_Find == TRUE) { |
| | | localLock.Unlock(); |
| | | return TRUE; |
| | | } |
| | | |
| | | /* |
| | | BOOL bBotCornerUse = (BOOL) (m_pRecipe->m_SideParam[emDim].m_nBottomCornerShape == 0) ? FALSE : TRUE; |
| | | |
| | | if(bBotCornerUse == FALSE) |
| | | BOOL bBotCornerUse = (BOOL)(m_pRecipe->m_SideParam[emDim].m_nBottomCornerShape == 0) ? FALSE : TRUE; |
| | | if (bBotCornerUse == FALSE) { |
| | | localLock.Unlock(); |
| | | return FALSE; |
| | | */ |
| | | } |
| | | |
| | | double dCornerSizeY_Um = (double) m_pRecipe->m_SideParam[emDim].m_nBottomCornerSizeY_um; |
| | | |
| | | int nCornerSizeY_Pixel = (int) GetUmToPixel_Y(dCornerSizeY_Um); |
| | | |
| | | int nFrameHeight = m_nFrameHeight; |
| | | |
| | | int nFindBottomLine = (pSideData->m_bFindGlassEndLine == TRUE) ? pSideData->m_nGlassEndLine : pSideData->m_nPreGlassEndLine; |
| | | |
| | | double dCornerSizeY_Um = (double)m_pRecipe->m_SideParam[emDim].m_nBottomCornerSizeY_um; |
| | | int nCornerSizeY_Pixel = (int)GetUmToPixel_Y(dCornerSizeY_Um); |
| | | int nFrameHeight = m_nFrameHeight; |
| | | int nFindBottomLine = (pSideData->m_bFindGlassEndLine == TRUE) ? pSideData->m_nGlassEndLine : pSideData->m_nPreGlassEndLine; |
| | | int nBottomCornerFrameIndex = (nFindBottomLine - nCornerSizeY_Pixel) / nFrameHeight; |
| | | |
| | | if((int) stFrame.nFrameIdx < nBottomCornerFrameIndex) |
| | | if ((int)stFrame.nFrameIdx < nBottomCornerFrameIndex) { |
| | | localLock.Unlock(); |
| | | return FALSE; |
| | | } |
| | | |
| | | // 澜.. 内呈 Side 扼牢捞 捞傈 橇饭烙俊 乐栏搁 绢录瘤.. 茄搁俊 Thread 啊 咯矾俺 倒搁?... 困 橇饭烙狼 Thread 啊 酒流 Side 扼牢阑 给茫疽栏搁.. 绊刮 粱 秦焊磊.. |
| | | // 荤捞靛喊 Thread绰 窍唱父 倒绊 八荤 Thread甫 咯矾俺 倒府绰 备炼肺 官层具摆促 |
| | | int nSideLine = pSideData->m_nSideLineFrame[nBottomCornerFrameIndex]; |
| | | nSideLine = (nSideLine == -1) ? pSideData->m_nSideLineFrame[nBottomCornerFrameIndex] : nSideLine; |
| | | // 음.. 코너 Side 라인이 이전 프레임에 있으면 어쩌지.. 한면에 Thread 가 여러개 돌면?... 위 프레임의 Thread 가 아직 Side 라인을 못찾았으면.. 고민 좀 해보자.. |
| | | // 사이드별 Thread는 하나만 돌고 검사 Thread를 여러개 돌리는 구조로 바꿔야겠다 |
| | | int nSideLine = (int)pSideData->m_nSideLineFrame[nBottomCornerFrameIndex]; |
| | | nSideLine = (nSideLine == -1) ? (int)pSideData->m_nSideLineFrame[nBottomCornerFrameIndex] : nSideLine; |
| | | |
| | | if(nSideLine == -1) |
| | | if (nSideLine == -1) { |
| | | localLock.Unlock(); |
| | | return FALSE; |
| | | } |
| | | |
| | | double dCornerSizeX_Um = (double) m_pRecipe->m_SideParam[emDim].m_nBottomCornerSizeX_um; |
| | | |
| | | int nCornerSizeX_Pixel = (int) GetUmToPixel_X(dCornerSizeX_Um); |
| | | double dCornerSizeX_Um = (double)m_pRecipe->m_SideParam[emDim].m_nBottomCornerSizeX_um; |
| | | int nCornerSizeX_Pixel = (int)GetUmToPixel_X(dCornerSizeX_Um); |
| | | |
| | | CRect rtBottomCornerArea(0, 0, nCornerSizeX_Pixel, nCornerSizeY_Pixel); |
| | | |
| | | rtBottomCornerArea.OffsetRect(nSideLine, nFindBottomLine-nCornerSizeY_Pixel); |
| | | rtBottomCornerArea.OffsetRect(nSideLine, nFindBottomLine - nCornerSizeY_Pixel); |
| | | |
| | | pSideData->m_bBotCorner_Find = TRUE; |
| | | pSideData->m_rtBotCornerArea = rtBottomCornerArea; |
| | |
| | | |
| | | int nBottomCornerType = m_pRecipe->m_SideParam[emDim].m_nBottomCornerShape; |
| | | |
| | | if(pSideParam->m_bBottomCornerFindDefect == FALSE) |
| | | if (pSideParam->m_bBottomCornerFindDefect == FALSE) { |
| | | localLock.Unlock(); |
| | | return FALSE; |
| | | } |
| | | |
| | | if(nBottomCornerType == (int) 1) return FindBotCorner_CCut(iThread, emDim, stFrame); |
| | | else if(nBottomCornerType == (int) 2) return FindBotCorner_RCut(iThread, emDim, stFrame); |
| | | localLock.Unlock(); |
| | | |
| | | if (nBottomCornerType == (int)1) return FindBotCorner_CCut(iThread, emDim, stFrame); |
| | | else if (nBottomCornerType == (int)2) return FindBotCorner_RCut(iThread, emDim, stFrame); |
| | | else return FindBotCorner_None(iThread, emDim, stFrame); |
| | | |
| | | return TRUE; |
| | | } |
| | | |
| | | BOOL CInspectCamera::FindBotCorner_None(int iThread,DimensionDir emDim, stFrameIndex stFrame) |
| | | BOOL CInspectCamera::FindBotCorner_None(int iThread, DimensionDir emDim, stFrameIndex stFrame) |
| | | { |
| | | if(m_pGlassData == NULL) |
| | | if (m_pGlassData == NULL) |
| | | return FALSE; |
| | | |
| | | CSide_Data* pSideData = m_pGlassData->GetSideData(emDim); |
| | | |
| | | if(pSideData == FALSE) |
| | | if (pSideData == FALSE) |
| | | return FALSE; |
| | | |
| | | CRect rtBotCornerArea = pSideData->m_rtBotCornerArea; |
| | | rtBotCornerArea.right = rtBotCornerArea.left + ALIGN_4BYTE(rtBotCornerArea.Width()); |
| | | |
| | | if(rtBotCornerArea.IsRectEmpty() || rtBotCornerArea.IsRectNull()) |
| | | if (rtBotCornerArea.IsRectEmpty() || rtBotCornerArea.IsRectNull()) |
| | | return FALSE; |
| | | |
| | | int nFrameWidth = m_nFrameWidth; |
| | | int nFrameWidth = m_nFrameWidth; |
| | | |
| | | // 1. Inspect ROI |
| | | COwnerBuffer pBuffer(rtBotCornerArea.Width(), rtBotCornerArea.Height()); |
| | |
| | | int nImageX = nInsStart; |
| | | int nImageY = rtBotCornerArea.Height() - 1 - i; |
| | | |
| | | if (nImageX < 0 ||rtBotCornerArea.Width() <= nImageX || nImageY < 0 || rtBotCornerArea.Height() <= nImageY) |
| | | if (nImageX < 0 || rtBotCornerArea.Width() <= nImageX || nImageY < 0 || rtBotCornerArea.Height() <= nImageY) |
| | | continue; |
| | | |
| | | int nRange = (rtBotCornerArea.Width() <= nImageX + nInsRange) ? (rtBotCornerArea.Width() - 1 - nImageX) : nInsRange; |
| | |
| | | return TRUE; |
| | | } |
| | | |
| | | BOOL CInspectCamera::FindBotCorner_CCut(int iThread,DimensionDir emDim, stFrameIndex stFrame) |
| | | BOOL CInspectCamera::FindBotCorner_CCut(int iThread, DimensionDir emDim, stFrameIndex stFrame) |
| | | { |
| | | if(m_pGlassData == NULL) |
| | | if (m_pGlassData == NULL) |
| | | return FALSE; |
| | | |
| | | CSide_Data* pSideData = m_pGlassData->GetSideData(emDim); |
| | | |
| | | if(pSideData == FALSE) |
| | | if (pSideData == FALSE) |
| | | return FALSE; |
| | | |
| | | CRect rtBotCornerArea = pSideData->m_rtBotCornerArea; |
| | | rtBotCornerArea.right = rtBotCornerArea.left + ALIGN_4BYTE(rtBotCornerArea.Width()); |
| | | |
| | | if(rtBotCornerArea.IsRectEmpty() || rtBotCornerArea.IsRectNull()) |
| | | if (rtBotCornerArea.IsRectEmpty() || rtBotCornerArea.IsRectNull()) |
| | | return FALSE; |
| | | |
| | | int nFrameWidth = m_nFrameWidth; |
| | | int nFrameWidth = m_nFrameWidth; |
| | | |
| | | // 1. Inspect ROI |
| | | COwnerBuffer pBuffer(rtBotCornerArea.Width(), rtBotCornerArea.Height()); |
| | |
| | | pSideData->m_rtBotCornerArea_Ins.bottom = pSideData->m_rtBotCornerArea_Offset.bottom - nInsRange; |
| | | pSideData->m_rtBotCornerArea_Ins.top = pSideData->m_rtBotCornerArea_Offset.top - nInsRange; |
| | | |
| | | double dScaleY = (double) rtBotCornerArea.Height() / (double)rtBotCornerArea.Width(); |
| | | double dScaleY = (double)rtBotCornerArea.Height() / (double)rtBotCornerArea.Width(); |
| | | |
| | | // 2. Make Masking.. |
| | | COwnerBuffer pMaskBuffer(rtBotCornerArea.Width(), rtBotCornerArea.Height()); |
| | |
| | | for (int i = 0; i < pMaskBuffer.GetWidth(); i++) |
| | | { |
| | | int nX = i; |
| | | int nY = (int) ((double)i * dScaleY) - nInsStart; |
| | | int nY = (int)((double)i * dScaleY) - nInsStart; |
| | | |
| | | if (nX < 0 || pMaskBuffer.GetWidth() <= nX || nY < 0 || pMaskBuffer.GetHeight() <= nY) |
| | | continue; |
| | | |
| | | int nRange = (nY - nInsRange < 0) ? nY : nInsRange; |
| | | |
| | | if(nRange == 0) |
| | | if (nRange == 0) |
| | | continue; |
| | | |
| | | for(int j=0; j<nRange; j++) |
| | | pMaskBuffer.SetPixel(nX, nY-j, 255); |
| | | for (int j = 0; j < nRange; j++) |
| | | pMaskBuffer.SetPixel(nX, nY - j, 255); |
| | | } |
| | | |
| | | // 3. Processing |
| | |
| | | return TRUE; |
| | | } |
| | | |
| | | BOOL CInspectCamera::FindBotCorner_RCut(int iThread,DimensionDir emDim, stFrameIndex stFrame) |
| | | BOOL CInspectCamera::FindBotCorner_RCut(int iThread, DimensionDir emDim, stFrameIndex stFrame) |
| | | { |
| | | if(m_pGlassData == NULL) |
| | | if (m_pGlassData == NULL) |
| | | return FALSE; |
| | | |
| | | CSide_Data* pSideData = m_pGlassData->GetSideData(emDim); |
| | | |
| | | if(pSideData == FALSE) |
| | | if (pSideData == FALSE) |
| | | return FALSE; |
| | | |
| | | CRect rtBotCornerArea = pSideData->m_rtBotCornerArea; |
| | | rtBotCornerArea.right = rtBotCornerArea.left + ALIGN_4BYTE(rtBotCornerArea.Width()); |
| | | |
| | | if(rtBotCornerArea.IsRectEmpty() || rtBotCornerArea.IsRectNull()) |
| | | if (rtBotCornerArea.IsRectEmpty() || rtBotCornerArea.IsRectNull()) |
| | | return FALSE; |
| | | |
| | | int nFrameWidth = m_nFrameWidth; |
| | | int nFrameWidth = m_nFrameWidth; |
| | | |
| | | // 1. Inspect ROI |
| | | COwnerBuffer pBuffer(rtBotCornerArea.Width(), rtBotCornerArea.Height()); |
| | |
| | | return TRUE; |
| | | } |
| | | |
| | | BOOL CInspectCamera::FindBotAlignMark(int iThread,DimensionDir eDim, stFrameIndex stFrame) |
| | | BOOL CInspectCamera::FindBotAlignMark(int iThread, DimensionDir eDim, stFrameIndex stFrame) |
| | | { |
| | | CSingleLock localLock(&m_csThreadBotAlignMark); |
| | | localLock.Lock(); |
| | | |
| | | if(m_pGlassData == NULL) |
| | | if (m_pGlassData == NULL) { |
| | | localLock.Unlock(); |
| | | return FALSE; |
| | | } |
| | | |
| | | CSide_Data* pSideData = m_pGlassData->GetSideData(eDim); |
| | | CSide_Data* pSideData = m_pGlassData->GetSideData(eDim); |
| | | |
| | | if(pSideData == NULL) |
| | | if (pSideData == NULL) { |
| | | localLock.Unlock(); |
| | | return FALSE; |
| | | } |
| | | |
| | | //if(pSideData->m_bBotCorner_Find == FALSE) |
| | | // return FALSE; |
| | | if (pSideData->m_bBotCorner_Find == FALSE) { |
| | | localLock.Unlock(); |
| | | return FALSE; |
| | | } |
| | | |
| | | if(pSideData->m_bBotMark_Find == TRUE) |
| | | if (pSideData->m_bBotMark_Find == TRUE) { |
| | | localLock.Unlock(); |
| | | return TRUE; |
| | | } |
| | | |
| | | BOOL bBotAlignMark = (BOOL) (m_pRecipe->m_SideParam[eDim].m_bBottomMark_Use == 1) ? TRUE : FALSE; |
| | | BOOL bBotAlignMark = (BOOL)(m_pRecipe->m_SideParam[eDim].m_bBottomMark_Use == 1) ? TRUE : FALSE; |
| | | |
| | | if(bBotAlignMark == FALSE) |
| | | if (bBotAlignMark == FALSE) { |
| | | localLock.Unlock(); |
| | | return FindBotAlignMark_Virtual(iThread, eDim, stFrame); |
| | | else |
| | | { |
| | | if(FindBotAlignMark_TempleteMatching(iThread, eDim, stFrame) == FALSE) |
| | | } |
| | | else { |
| | | if (FindBotAlignMark_TempleteMatching(iThread, eDim, stFrame) == FALSE) { |
| | | localLock.Unlock(); |
| | | return FindBotAlignMark_Virtual(iThread, eDim, stFrame); |
| | | else |
| | | } |
| | | else { |
| | | localLock.Unlock(); |
| | | return TRUE; |
| | | } |
| | | } |
| | | } |
| | | |
| | | BOOL CInspectCamera::FindBotAlignMark_Virtual(int iThread,DimensionDir eDim, stFrameIndex stFrame) |
| | | BOOL CInspectCamera::FindBotAlignMark_Virtual(int iThread, DimensionDir eDim, stFrameIndex stFrame) |
| | | { |
| | | if(m_pGlassData == NULL) |
| | | if (m_pGlassData == NULL) |
| | | return FALSE; |
| | | |
| | | CSide_Data* pSideData = m_pGlassData->GetSideData(eDim); |
| | | CSide_Data* pSideData = m_pGlassData->GetSideData(eDim); |
| | | |
| | | if(pSideData == NULL) |
| | | if (pSideData == NULL) |
| | | return FALSE; |
| | | |
| | | //if(pSideData->m_bBotCorner_Find == FALSE) |
| | | // return FALSE; |
| | | //if(pSideData->m_bBotCorner_Find == FALSE) |
| | | // return FALSE; |
| | | |
| | | if(pSideData->m_bBotMark_Find == TRUE) |
| | | if (pSideData->m_bBotMark_Find == TRUE) |
| | | return TRUE; |
| | | |
| | | // 1. Make ROI |
| | | int nFrameWidth = m_nFrameWidth; |
| | | int nFrameHeight = m_nFrameHeight; |
| | | int nFrameWidth = m_nFrameWidth; |
| | | int nFrameHeight = m_nFrameHeight; |
| | | |
| | | int nEndLine = (pSideData->m_bFindGlassEndLine == TRUE) ? pSideData->m_nGlassEndLine : pSideData->m_nPreGlassEndLine; |
| | | double dEdgeToBottomAlignMarkY_Um = m_pRecipe->m_SideParam[eDim].m_nBottomMarkToEdgeY_um; |
| | | int nEdgeToBottomAlignMarkY_Pixel = (int) GetUmToPixel_Y(dEdgeToBottomAlignMarkY_Um); |
| | | int nBottomAlignMarkY_Pixel = nEndLine - nEdgeToBottomAlignMarkY_Pixel; |
| | | int nEndLine = (pSideData->m_bFindGlassEndLine == TRUE) ? pSideData->m_nGlassEndLine : pSideData->m_nPreGlassEndLine; |
| | | double dEdgeToBottomAlignMarkY_Um = m_pRecipe->m_SideParam[eDim].m_nBottomMarkToEdgeY_um; |
| | | int nEdgeToBottomAlignMarkY_Pixel = (int)GetUmToPixel_Y(dEdgeToBottomAlignMarkY_Um); |
| | | int nBottomAlignMarkY_Pixel = nEndLine - nEdgeToBottomAlignMarkY_Pixel; |
| | | |
| | | int nBottomCornerTopFrameIndex = nBottomAlignMarkY_Pixel / nFrameHeight; //pSideData->m_rtBotCornerArea.top / nFrameHeight; |
| | | |
| | | int nGlassEndLine = (pSideData->m_bFindGlassEndLine == TRUE) ? pSideData->m_nGlassEndLine : pSideData->m_nPreGlassEndLine; |
| | | int nGlassEndLineFrame = nGlassEndLine / nFrameHeight; |
| | | |
| | | if((int) stFrame.nFrameIdx < nGlassEndLineFrame) |
| | | if ((int)stFrame.nFrameIdx < nGlassEndLineFrame) |
| | | return FALSE; |
| | | |
| | | int nSideLine = pSideData->m_nSideLineFrame[nBottomCornerTopFrameIndex]; |
| | | double nEdgeToBotAlignMarkX_Um = m_pRecipe->m_SideParam[eDim].m_nBottomMarkToEdgeX_um; |
| | | int nEdgeToBotAlignMarkX_Pixel = (int) GetUmToPixel_X(nEdgeToBotAlignMarkX_Um); |
| | | int nBottomAlignMarkX_Pixel = nSideLine + nEdgeToBotAlignMarkX_Pixel; |
| | | int nSideLine = (int)pSideData->m_nSideLineFrame[nBottomCornerTopFrameIndex]; |
| | | double nEdgeToBotAlignMarkX_Um = m_pRecipe->m_SideParam[eDim].m_nBottomMarkToEdgeX_um; |
| | | int nEdgeToBotAlignMarkX_Pixel = (int)GetUmToPixel_X(nEdgeToBotAlignMarkX_Um); |
| | | int nBottomAlignMarkX_Pixel = nSideLine + nEdgeToBotAlignMarkX_Pixel; |
| | | |
| | | CRect rtSearchArea = CRect(nBottomAlignMarkX_Pixel, nBottomAlignMarkY_Pixel, nBottomAlignMarkX_Pixel, nBottomAlignMarkY_Pixel); |
| | | rtSearchArea.InflateRect(50, 50); |
| | |
| | | return TRUE; |
| | | } |
| | | |
| | | BOOL CInspectCamera::FindBotAlignMark_TempleteMatching(int iThread,DimensionDir eDim, stFrameIndex stFrame) |
| | | BOOL CInspectCamera::FindBotAlignMark_TempleteMatching(int iThread, DimensionDir eDim, stFrameIndex stFrame) |
| | | { |
| | | if(m_pGlassData == NULL) |
| | | if (m_pGlassData == NULL) |
| | | return FALSE; |
| | | |
| | | CSide_Data* pSideData = m_pGlassData->GetSideData(eDim); |
| | | CSide_Data* pSideData = m_pGlassData->GetSideData(eDim); |
| | | |
| | | if(pSideData == NULL) |
| | | if (pSideData == NULL) |
| | | return FALSE; |
| | | |
| | | if(pSideData->m_bBotMark_Find == TRUE) |
| | | if (pSideData->m_bBotMark_Find == TRUE) |
| | | return TRUE; |
| | | |
| | | //if(pSideData->m_bBotCorner_Find == FALSE) |
| | | // return FALSE; |
| | | //if(pSideData->m_bBotCorner_Find == FALSE) |
| | | // return FALSE; |
| | | |
| | | // 1. Make ROI |
| | | int nFrameWidth = m_nFrameWidth; |
| | | int nFrameHeight = m_nFrameHeight; |
| | | int nFrameWidth = m_nFrameWidth; |
| | | int nFrameHeight = m_nFrameHeight; |
| | | |
| | | int nEndLine = (pSideData->m_bFindGlassEndLine == TRUE) ? pSideData->m_nGlassEndLine : pSideData->m_nPreGlassEndLine; |
| | | double dEdgeToBottomAlignMarkY_Um = m_pRecipe->m_SideParam[eDim].m_nBottomMarkToEdgeY_um; |
| | | int nEdgeToBottomAlignMarkY_Pixel = (int) GetUmToPixel_Y(dEdgeToBottomAlignMarkY_Um); |
| | | int nBottomAlignMarkY_Pixel = nEndLine - nEdgeToBottomAlignMarkY_Pixel; |
| | | int nEndLine = (pSideData->m_bFindGlassEndLine == TRUE) ? pSideData->m_nGlassEndLine : pSideData->m_nPreGlassEndLine; |
| | | double dEdgeToBottomAlignMarkY_Um = m_pRecipe->m_SideParam[eDim].m_nBottomMarkToEdgeY_um; |
| | | int nEdgeToBottomAlignMarkY_Pixel = (int)GetUmToPixel_Y(dEdgeToBottomAlignMarkY_Um); |
| | | int nBottomAlignMarkY_Pixel = nEndLine - nEdgeToBottomAlignMarkY_Pixel; |
| | | |
| | | int nBottomCornerTopFrameIndex = nBottomAlignMarkY_Pixel / nFrameHeight; // pSideData->m_rtBotCornerArea.top / nFrameHeight; |
| | | |
| | | int nGlassEndLine = (pSideData->m_bFindGlassEndLine == TRUE) ? pSideData->m_nGlassEndLine : pSideData->m_nPreGlassEndLine; |
| | | int nGlassEndLineFrame = nGlassEndLine / nFrameHeight; |
| | | |
| | | if((int) stFrame.nFrameIdx < nGlassEndLineFrame) |
| | | if ((int)stFrame.nFrameIdx < nGlassEndLineFrame) |
| | | return FALSE; |
| | | |
| | | int nSideLine = pSideData->m_nSideLineFrame[nBottomCornerTopFrameIndex]; |
| | | if(nSideLine <= 0) |
| | | int nSideLine = (int)pSideData->m_nSideLineFrame[nBottomCornerTopFrameIndex]; |
| | | if (nSideLine <= 0) |
| | | { |
| | | CRect rectSide = CRect(0,nBottomAlignMarkY_Pixel,nFrameWidth-1,nBottomAlignMarkY_Pixel); |
| | | CRect rectSide = CRect(0, nBottomAlignMarkY_Pixel, nFrameWidth - 1, nBottomAlignMarkY_Pixel); |
| | | |
| | | rectSide.InflateRect(0,30); |
| | | rectSide.InflateRect(0, 30); |
| | | |
| | | CSISBuffer frameBuffer(m_pGrabber->GetFrameHeaderLine(stFrame.nScanIdx, rectSide.top),nFrameWidth,rectSide.Height()); |
| | | CSISBuffer frameBuffer(m_pGrabber->GetFrameHeaderLine(stFrame.nScanIdx, rectSide.top), nFrameWidth, rectSide.Height()); |
| | | |
| | | if(frameBuffer.IsValidBuffer() == FALSE) |
| | | if (frameBuffer.IsValidBuffer() == FALSE) |
| | | return FALSE; |
| | | |
| | | rectSide.OffsetRect(0, -rectSide.top); |
| | | |
| | | int nThres = m_pRecipe->m_SideParam[(int)(eDim)].m_nSideLineThreshold; |
| | | int nThres = m_pRecipe->m_SideParam[(int)(eDim)].m_nSideLineThreshold; |
| | | |
| | | CSISEdgeFind EdgeFind; |
| | | EdgeFind.FindEdge_ToRightROI(&frameBuffer,nSideLine,DEFECT_EDGE_AUTO_PITCH,nThres,DEFECT_EDGE_AUTO_RATIO,0,rectSide); |
| | | EdgeFind.FindEdge_ToRightROI(&frameBuffer, nSideLine, DEFECT_EDGE_AUTO_PITCH, nThres, DEFECT_EDGE_AUTO_RATIO, 0, rectSide); |
| | | } |
| | | |
| | | if(nSideLine <= 0) |
| | | if (nSideLine <= 0) |
| | | return FALSE; |
| | | |
| | | double nEdgeToBotAlignMarkX_Um = m_pRecipe->m_SideParam[eDim].m_nBottomMarkToEdgeX_um; |
| | | int nEdgeToBotAlignMarkX_Pixel = (int) GetUmToPixel_X(nEdgeToBotAlignMarkX_Um); |
| | | int nBottomAlignMarkX_Pixel = nSideLine + nEdgeToBotAlignMarkX_Pixel; |
| | | double nEdgeToBotAlignMarkX_Um = m_pRecipe->m_SideParam[eDim].m_nBottomMarkToEdgeX_um; |
| | | int nEdgeToBotAlignMarkX_Pixel = (int)GetUmToPixel_X(nEdgeToBotAlignMarkX_Um); |
| | | int nBottomAlignMarkX_Pixel = nSideLine + nEdgeToBotAlignMarkX_Pixel; |
| | | |
| | | double dTarget_Rate = m_pRecipe->m_SideParam[(int) eDim].m_dBottomMarkTemplateMatchingRate / 100.0; |
| | | double dTarget_Rate = m_pRecipe->m_SideParam[(int)eDim].m_dBottomMarkTemplateMatchingRate / 100.0; |
| | | |
| | | CvPoint ptMax_Point; |
| | | double dMat_Max_Rate; |
| | | double dMat_Min_Rate; |
| | | |
| | | for(int i=0 ; i<MAX_MARKER_COUNT ; i++) |
| | | for (int i = 0; i < MAX_MARKER_COUNT; i++) |
| | | { |
| | | USES_CONVERSION; |
| | | USES_CONVERSION; |
| | | char str_filename[256]; |
| | | sprintf_s(str_filename, "%s\\%s\\Side_%d_BotAlign_%d.bmp", W2A(RECIPE_ALIGN_PATH), W2A(m_pRecipe->GetRecipeName()), (int) eDim, i); |
| | | sprintf_s(str_filename, "%s\\%s\\Side_%d_BotAlign_%d.bmp", W2A(RECIPE_ALIGN_PATH), W2A(m_pRecipe->GetRecipeName()), (int)eDim, i); |
| | | |
| | | IplImage* pTemplateImage = cvLoadImage(str_filename, CV_LOAD_IMAGE_GRAYSCALE); |
| | | if(pTemplateImage == NULL) |
| | | if (pTemplateImage == NULL) |
| | | continue; |
| | | |
| | | CRect rtSearchArea = CRect(nBottomAlignMarkX_Pixel, nBottomAlignMarkY_Pixel, nBottomAlignMarkX_Pixel, nBottomAlignMarkY_Pixel); |
| | | rtSearchArea.InflateRect(pTemplateImage->width * 2, pTemplateImage->height * 2); |
| | | |
| | | CSISBuffer frameBuffer(m_pGrabber->GetFrameHeaderLine(stFrame.nScanIdx,rtSearchArea.top), nFrameWidth, rtSearchArea.Height()); |
| | | CSISBuffer frameBuffer(m_pGrabber->GetFrameHeaderLine(stFrame.nScanIdx, rtSearchArea.top), nFrameWidth, rtSearchArea.Height()); |
| | | |
| | | if(!frameBuffer.IsValidBuffer()) |
| | | if (!frameBuffer.IsValidBuffer()) |
| | | continue; |
| | | |
| | | pSideData->m_rtBotMark_SearchArea = rtSearchArea; |
| | | |
| | | IplImage* scr = cvCreateImage(cvSize(rtSearchArea.Width(),rtSearchArea.Height()),8,1); |
| | | IplImage* scr = cvCreateImage(cvSize(rtSearchArea.Width(), rtSearchArea.Height()), 8, 1); |
| | | |
| | | for(int i=0; i<rtSearchArea.Height(); i++) |
| | | for (int i = 0; i < rtSearchArea.Height(); i++) |
| | | memcpy(&scr->imageData[i * scr->widthStep], frameBuffer.GetDataAddress(rtSearchArea.left, i), rtSearchArea.Width()); |
| | | |
| | | IplImage* ResultImage = cvCreateImage(cvSize(scr->width - pTemplateImage->width+1, scr->height - pTemplateImage->height+1 ),32,1); |
| | | IplImage* ResultImage = cvCreateImage(cvSize(scr->width - pTemplateImage->width + 1, scr->height - pTemplateImage->height + 1), 32, 1); |
| | | |
| | | cvMatchTemplate(scr, pTemplateImage, ResultImage, CV_TM_CCOEFF_NORMED); |
| | | cvMinMaxLoc(ResultImage, &dMat_Min_Rate, &dMat_Max_Rate, NULL, &ptMax_Point); |
| | | |
| | | ptMax_Point.x += pTemplateImage->width/2; |
| | | ptMax_Point.y += pTemplateImage->height/2; |
| | | ptMax_Point.x += pTemplateImage->width / 2; |
| | | ptMax_Point.y += pTemplateImage->height / 2; |
| | | int nTemplateW = pTemplateImage->width; |
| | | int nTemplateH = pTemplateImage->height; |
| | | |
| | |
| | | cvReleaseImage(&pTemplateImage); |
| | | cvReleaseImage(&scr); |
| | | |
| | | if(dMat_Max_Rate > dTarget_Rate) |
| | | if (dMat_Max_Rate > dTarget_Rate) |
| | | { |
| | | pSideData->m_bBotMark_Find = TRUE; |
| | | pSideData->m_rtBotMark_SearchArea = rtSearchArea; |
| | | pSideData->m_ptBotMark_FindResult = CPoint(ptMax_Point.x, ptMax_Point.y); |
| | | pSideData->m_ptBotMark_FindResult.Offset(rtSearchArea.left, rtSearchArea.top); |
| | | pSideData->m_rtBotMark_FindResult = CRect(pSideData->m_ptBotMark_FindResult, pSideData->m_ptBotMark_FindResult); |
| | | pSideData->m_rtBotMark_FindResult.InflateRect(nTemplateW/2, nTemplateH/2); |
| | | pSideData->m_rtBotMark_FindResult.InflateRect(nTemplateW / 2, nTemplateH / 2); |
| | | |
| | | return TRUE; |
| | | } |
| | | } |
| | | } |
| | | |
| | | // Make Mark Defect.. |
| | | CDefect_Info defectInfo; |
| | | defectInfo.m_iFrameIdx = stFrame.nFrameIdx; |
| | | defectInfo.m_nCamID = m_iCamera; |
| | | defectInfo.m_nScanIdx = stFrame.nScanIdx; |
| | | defectInfo.m_nGlassStartLine = m_pGlassData->GetSideData(eDim)->m_nGlassStartLine; |
| | | defectInfo.m_nSideIdx = (int) eDim; |
| | | defectInfo.m_ptDefectPos_pxl = pSideData->m_rtBotMark_SearchArea.CenterPoint(); |
| | | defectInfo.m_rtDefectPos_pxl = pSideData->m_rtBotMark_SearchArea; |
| | | defectInfo.m_DefectLoc = DefectLoc_Mark; |
| | | defectInfo.m_iFrameIdx = stFrame.nFrameIdx; |
| | | defectInfo.m_nCamID = m_iCamera; |
| | | defectInfo.m_nScanIdx = stFrame.nScanIdx; |
| | | defectInfo.m_nGlassStartLine = m_pGlassData->GetSideData(eDim)->m_nGlassStartLine; |
| | | defectInfo.m_nSideIdx = (int)eDim; |
| | | defectInfo.m_ptDefectPos_pxl = pSideData->m_rtBotMark_SearchArea.CenterPoint(); |
| | | defectInfo.m_rtDefectPos_pxl = pSideData->m_rtBotMark_SearchArea; |
| | | defectInfo.m_DefectLoc = DefectLoc_Mark; |
| | | |
| | | m_pDefectControl->ExtractDefect_Mark(eDim, m_iCamera, stFrame.nScanIdx, defectInfo); |
| | | |
| | | return FALSE; |
| | | } |
| | | |
| | | BOOL CInspectCamera::InspectDefect(int iThread,DimensionDir eDim, stFrameIndex stFrame) |
| | | BOOL CInspectCamera::InspectDefect(int iThread, DimensionDir eDim, stFrameIndex stFrame) |
| | | { |
| | | CRect rtInspectArea; |
| | | int nCutLine = 0; |
| | | |
| | | if(MakeInspectRegion(iThread, eDim, stFrame.nScanIdx, stFrame.nFrameIdx, rtInspectArea, nCutLine) == FALSE) |
| | | if (MakeInspectRegion(iThread, eDim, stFrame.nScanIdx, stFrame.nFrameIdx, rtInspectArea, nCutLine) == FALSE) |
| | | return FALSE; |
| | | |
| | | // Inspect Area. |
| | |
| | | |
| | | std::vector<CDefect_Info> vecDefectCandidateList; |
| | | |
| | | for(int i=0; i<MAX_SIDE_INSPECT_TYPE; i++) |
| | | for (int i = 0; i < MAX_SIDE_INSPECT_TYPE; i++) |
| | | { |
| | | InspectDefect_Process(iThread, eDim, stFrame.nScanIdx, stFrame.nFrameIdx, rtInspectArea, nCutLine, (eSideInsType) i, &vecDefectCandidateList); |
| | | InspectDefect_Process(iThread, eDim, stFrame.nScanIdx, stFrame.nFrameIdx, rtInspectArea, nCutLine, (eSideInsType)i, &vecDefectCandidateList); |
| | | } |
| | | |
| | | m_pDefectControl->ExtractDefect_Side(eDim, m_iCamera, stFrame.nScanIdx, &vecDefectCandidateList); |
| | |
| | | return TRUE; |
| | | } |
| | | |
| | | BOOL CInspectCamera::InspectDefect_Side(int iThread,DimensionDir eDim, stFrameIndex stFrame) |
| | | BOOL CInspectCamera::InspectDefect_Side(int iThread, DimensionDir eDim, stFrameIndex stFrame) |
| | | { |
| | | std::vector<CRect> vecInspectAreaList; // For Notch Region Divide.. |
| | | int nCutLine = 0; |
| | | |
| | | if(MakeInspectRegion(iThread, eDim, stFrame.nScanIdx, stFrame.nFrameIdx, vecInspectAreaList, nCutLine) == FALSE) |
| | | if (MakeInspectRegion(iThread, eDim, stFrame.nScanIdx, stFrame.nFrameIdx, vecInspectAreaList, nCutLine) == FALSE) |
| | | return FALSE; |
| | | |
| | | // Inspect Area. |
| | | m_pGlassData->GetSideData(eDim)->m_nSideInspectAreaCount[stFrame.nFrameIdx] = vecInspectAreaList.size(); |
| | | |
| | | for(int nRegionIdx=0; nRegionIdx<vecInspectAreaList.size(); nRegionIdx++) |
| | | for (int nRegionIdx = 0; nRegionIdx < vecInspectAreaList.size(); nRegionIdx++) |
| | | { |
| | | if(MAX_SIDE_INSPECT_AREA_COUNT <= nRegionIdx) |
| | | if (MAX_SIDE_INSPECT_AREA_COUNT <= nRegionIdx) |
| | | continue; |
| | | |
| | | m_pGlassData->GetSideData(eDim)->m_rtInspectArea[stFrame.nFrameIdx] = vecInspectAreaList[nRegionIdx]; |
| | |
| | | |
| | | std::vector<CDefect_Info> vecDefectCandidateList; |
| | | |
| | | for(int i=0; i<MAX_SIDE_INSPECT_TYPE; i++) |
| | | for (int i = 0; i < MAX_SIDE_INSPECT_TYPE; i++) |
| | | { |
| | | InspectDefect_Process(iThread, eDim, stFrame.nScanIdx, stFrame.nFrameIdx, vecInspectAreaList[nRegionIdx], nCutLine, (eSideInsType) i, &vecDefectCandidateList); |
| | | InspectDefect_Process(iThread, eDim, stFrame.nScanIdx, stFrame.nFrameIdx, vecInspectAreaList[nRegionIdx], nCutLine, (eSideInsType)i, &vecDefectCandidateList); |
| | | } |
| | | |
| | | m_pDefectControl->ExtractDefect_Side(eDim, m_iCamera, stFrame.nScanIdx, &vecDefectCandidateList); |
| | |
| | | return TRUE; |
| | | } |
| | | |
| | | BOOL CInspectCamera::MakeInspectRegion(int iThread,DimensionDir eDim,int iScan,int iFrame, CRect& rtInspectArea, int& nCutLine) |
| | | BOOL CInspectCamera::MakeInspectRegion(int iThread, DimensionDir eDim, int iScan, int iFrame, CRect& rtInspectArea, int& nCutLine) |
| | | { |
| | | CSide_Data* pSideData = m_pGlassData->GetSideData(eDim); |
| | | if(pSideData == NULL) |
| | | if (pSideData == NULL) |
| | | return FALSE; |
| | | |
| | | if(pSideData->m_nSideLineFrame[iFrame] < 0) // Side Line阑 给茫篮 版快.. |
| | | if (pSideData->m_nSideLineFrame[iFrame] < 0) // Side Line을 못찾은 경우.. |
| | | return FALSE; |
| | | |
| | | // 1. Make Corner Area |
| | | int nFindStartLine = pSideData->m_nGlassStartLine; |
| | | double dTopCornerSizeY_UM = m_pRecipe->m_SideParam[eDim].m_nTopCornerSizeY_um; |
| | | int nTopCornerYSizePixel = (int) GetUmToPixel_Y(dTopCornerSizeY_UM); |
| | | int nTopCornerEndLine = nFindStartLine + nTopCornerYSizePixel; |
| | | int nFindStartLine = pSideData->m_nGlassStartLine; |
| | | double dTopCornerSizeY_UM = m_pRecipe->m_SideParam[eDim].m_nTopCornerSizeY_um; |
| | | int nTopCornerYSizePixel = (int)GetUmToPixel_Y(dTopCornerSizeY_UM); |
| | | int nTopCornerEndLine = nFindStartLine + nTopCornerYSizePixel; |
| | | |
| | | int nFindEndLine = (pSideData->m_bFindGlassEndLine == TRUE) ? pSideData->m_nGlassEndLine : pSideData->m_nPreGlassEndLine; |
| | | double dBottomCornerSizeY_UM = m_pRecipe->m_SideParam[eDim].m_nBottomCornerSizeY_um; |
| | | int nBottomCornerYSizePixel = (int) GetUmToPixel_Y(dBottomCornerSizeY_UM); |
| | | int nBottomCornerStartLine = nFindEndLine - nBottomCornerYSizePixel; |
| | | int nFindEndLine = (pSideData->m_bFindGlassEndLine == TRUE) ? pSideData->m_nGlassEndLine : pSideData->m_nPreGlassEndLine; |
| | | double dBottomCornerSizeY_UM = m_pRecipe->m_SideParam[eDim].m_nBottomCornerSizeY_um; |
| | | int nBottomCornerYSizePixel = (int)GetUmToPixel_Y(dBottomCornerSizeY_UM); |
| | | int nBottomCornerStartLine = nFindEndLine - nBottomCornerYSizePixel; |
| | | |
| | | // 2. Max Inspect Area.. |
| | | CRect rtFrame; |
| | | rtFrame.left = pSideData->m_nSide_Chamfer_LineFrame[iFrame]; |
| | | rtFrame.top = iFrame * m_nFrameHeight; |
| | | rtFrame.right = rtFrame.left; |
| | | rtFrame.bottom = rtFrame.top + m_nFrameHeight; |
| | | |
| | | //rtFrame.top = rtFrame.top; // 困肺 炼陛 歹 八荤秦辑 搬窃捞 钦媚瘤霸 秦焊磊.. |
| | | rtFrame.top = rtFrame.top - 100; // 100 Pixel Frame 唱床柳 版快 巩力啊 登聪, 吝汗 八荤窍磊.. |
| | | rtFrame.left = (LONG)pSideData->m_nSide_Chamfer_LineFrame[iFrame]; |
| | | rtFrame.top = iFrame * m_nFrameHeight; |
| | | rtFrame.right = rtFrame.left; |
| | | rtFrame.bottom = rtFrame.top + m_nFrameHeight; |
| | | |
| | | int nMaxInspectRange = 0; |
| | | //rtFrame.top = rtFrame.top; // 위로 조금 더 검사해서 결함이 합쳐지게 해보자.. |
| | | rtFrame.top = rtFrame.top - 100; // 100 Pixel Frame 나눠진 경우 문제가 되니, 중복 검사하자.. |
| | | |
| | | for(int i=0; i<MAX_SIDE_INSPECT_TYPE; i++) |
| | | int nMaxInspectRange = 0; |
| | | |
| | | for (int i = 0; i < MAX_SIDE_INSPECT_TYPE; i++) |
| | | { |
| | | if(m_pRecipe->m_SideParam[(int) eDim].m_InspectPrm[i].m_bUseInspect == TRUE) |
| | | if (m_pRecipe->m_SideParam[(int)eDim].m_InspectPrm[i].m_bUseInspect == TRUE) |
| | | { |
| | | int nSideLineOffset_pxl = (int) GetUmToPixel_X((double) m_pRecipe->m_SideParam[(int) eDim].m_InspectPrm[i].m_nInspect_SideLine_Offset_um); |
| | | int nInspect_Range_pxl = (int) GetUmToPixel_X((double) m_pRecipe->m_SideParam[(int) eDim].m_InspectPrm[i].m_nInspect_Range_um); |
| | | int nSideLineOffset_pxl = (int)GetUmToPixel_X((double)m_pRecipe->m_SideParam[(int)eDim].m_InspectPrm[i].m_nInspect_SideLine_Offset_um); |
| | | int nInspect_Range_pxl = (int)GetUmToPixel_X((double)m_pRecipe->m_SideParam[(int)eDim].m_InspectPrm[i].m_nInspect_Range_um); |
| | | |
| | | int nInsRange = abs(nSideLineOffset_pxl) + abs(nInspect_Range_pxl); |
| | | nMaxInspectRange = (nMaxInspectRange < nInsRange) ? nInsRange : nMaxInspectRange; |
| | | int nInsRange = abs(nSideLineOffset_pxl) + abs(nInspect_Range_pxl); |
| | | nMaxInspectRange = (nMaxInspectRange < nInsRange) ? nInsRange : nMaxInspectRange; |
| | | } |
| | | } |
| | | rtFrame.InflateRect(nMaxInspectRange, 0); |
| | | |
| | | // 2. Make Roi, Exception Corner Area |
| | | CRect rtGlassSideROI; |
| | | rtGlassSideROI.left = 0; |
| | | rtGlassSideROI.top = (nTopCornerEndLine < nFindStartLine) ? nFindStartLine : nTopCornerEndLine; |
| | | rtGlassSideROI.right = m_nFrameWidth; |
| | | rtGlassSideROI.bottom = nBottomCornerStartLine; |
| | | rtGlassSideROI.left = 0; |
| | | rtGlassSideROI.top = (nTopCornerEndLine < nFindStartLine) ? nFindStartLine : nTopCornerEndLine; |
| | | rtGlassSideROI.right = m_nFrameWidth; |
| | | rtGlassSideROI.bottom = nBottomCornerStartLine; |
| | | |
| | | nCutLine = rtFrame.CenterPoint().x; |
| | | |
| | | // 3. Return Inspect Area.. |
| | | rtInspectArea.IntersectRect(rtFrame, rtGlassSideROI); |
| | | |
| | | if(rtInspectArea.IsRectEmpty() || rtInspectArea.IsRectNull()) |
| | | if (rtInspectArea.IsRectEmpty() || rtInspectArea.IsRectNull()) |
| | | return FALSE; |
| | | |
| | | rtInspectArea.right = rtInspectArea.left + align_4byte(rtInspectArea.Width()); |
| | |
| | | return TRUE; |
| | | } |
| | | |
| | | BOOL CInspectCamera::MakeInspectRegion(int iThread,DimensionDir eDim,int iScan,int iFrame, std::vector<CRect> & vecInspectArea, int& nCutLine) |
| | | BOOL CInspectCamera::MakeInspectRegion(int iThread, DimensionDir eDim, int iScan, int iFrame, std::vector<CRect>& vecInspectArea, int& nCutLine) |
| | | { |
| | | CSide_Data* pSideData = m_pGlassData->GetSideData(eDim); |
| | | if(pSideData == NULL) |
| | | if (pSideData == NULL) |
| | | return FALSE; |
| | | |
| | | if(pSideData->m_nSideLineFrame[iFrame] < 0) // Side Line阑 给茫篮 版快.. |
| | | if (pSideData->m_nSideLineFrame[iFrame] < 0) // Side Line을 못찾은 경우.. |
| | | return FALSE; |
| | | |
| | | // 1. Make Corner Area |
| | | int nFindStartLine = pSideData->m_nGlassStartLine; |
| | | double dTopCornerSizeY_UM = m_pRecipe->m_SideParam[eDim].m_nTopCornerSizeY_um; |
| | | int nTopCornerYSizePixel = (int) GetUmToPixel_Y(dTopCornerSizeY_UM); |
| | | int nTopCornerEndLine = nFindStartLine + nTopCornerYSizePixel; |
| | | int nFindStartLine = pSideData->m_nGlassStartLine; |
| | | double dTopCornerSizeY_UM = m_pRecipe->m_SideParam[eDim].m_nTopCornerSizeY_um; |
| | | int nTopCornerYSizePixel = (int)GetUmToPixel_Y(dTopCornerSizeY_UM); |
| | | int nTopCornerEndLine = nFindStartLine + nTopCornerYSizePixel; |
| | | |
| | | int nFindEndLine = (pSideData->m_bFindGlassEndLine == TRUE) ? pSideData->m_nGlassEndLine : pSideData->m_nPreGlassEndLine; |
| | | double dBottomCornerSizeY_UM = m_pRecipe->m_SideParam[eDim].m_nBottomCornerSizeY_um; |
| | | int nBottomCornerYSizePixel = (int) GetUmToPixel_Y(dBottomCornerSizeY_UM); |
| | | int nBottomCornerStartLine = nFindEndLine - nBottomCornerYSizePixel; |
| | | int nFindEndLine = (pSideData->m_bFindGlassEndLine == TRUE) ? pSideData->m_nGlassEndLine : pSideData->m_nPreGlassEndLine; |
| | | double dBottomCornerSizeY_UM = m_pRecipe->m_SideParam[eDim].m_nBottomCornerSizeY_um; |
| | | int nBottomCornerYSizePixel = (int)GetUmToPixel_Y(dBottomCornerSizeY_UM); |
| | | int nBottomCornerStartLine = nFindEndLine - nBottomCornerYSizePixel; |
| | | |
| | | // 2. Max Inspect Area.. |
| | | CRect rtFrame; |
| | | rtFrame.left = pSideData->m_nSide_Chamfer_LineFrame[iFrame]; |
| | | rtFrame.top = iFrame * m_nFrameHeight; |
| | | rtFrame.right = rtFrame.left; |
| | | rtFrame.bottom = rtFrame.top + m_nFrameHeight; |
| | | rtFrame.left = (LONG)pSideData->m_nSide_Chamfer_LineFrame[iFrame]; |
| | | rtFrame.top = iFrame * m_nFrameHeight; |
| | | rtFrame.right = rtFrame.left; |
| | | rtFrame.bottom = rtFrame.top + m_nFrameHeight; |
| | | |
| | | //rtFrame.top = rtFrame.top; // 困肺 炼陛 歹 八荤秦辑 搬窃捞 钦媚瘤霸 秦焊磊.. |
| | | rtFrame.top = rtFrame.top - 100; // 100 Pixel Frame 唱床柳 版快 巩力啊 登聪, 吝汗 八荤窍磊.. |
| | | //rtFrame.top = rtFrame.top; // 위로 조금 더 검사해서 결함이 합쳐지게 해보자.. |
| | | rtFrame.top = rtFrame.top - 100; // 100 Pixel Frame 나눠진 경우 문제가 되니, 중복 검사하자.. |
| | | |
| | | int nMaxInspectRange = 0; |
| | | int nMaxInspectRange = 0; |
| | | |
| | | for(int i=0; i<MAX_SIDE_INSPECT_TYPE; i++) |
| | | for (int i = 0; i < MAX_SIDE_INSPECT_TYPE; i++) |
| | | { |
| | | if(m_pRecipe->m_SideParam[(int) eDim].m_InspectPrm[i].m_bUseInspect == TRUE) |
| | | if (m_pRecipe->m_SideParam[(int)eDim].m_InspectPrm[i].m_bUseInspect == TRUE) |
| | | { |
| | | int nSideLineOffset_pxl = (int) GetUmToPixel_X((double) m_pRecipe->m_SideParam[(int) eDim].m_InspectPrm[i].m_nInspect_SideLine_Offset_um); |
| | | int nInspect_Range_pxl = (int) GetUmToPixel_X((double) m_pRecipe->m_SideParam[(int) eDim].m_InspectPrm[i].m_nInspect_Range_um); |
| | | int nSideLineOffset_pxl = (int)GetUmToPixel_X((double)m_pRecipe->m_SideParam[(int)eDim].m_InspectPrm[i].m_nInspect_SideLine_Offset_um); |
| | | int nInspect_Range_pxl = (int)GetUmToPixel_X((double)m_pRecipe->m_SideParam[(int)eDim].m_InspectPrm[i].m_nInspect_Range_um); |
| | | |
| | | int nInsRange = abs(nSideLineOffset_pxl) + abs(nInspect_Range_pxl); |
| | | nMaxInspectRange = (nMaxInspectRange < nInsRange) ? nInsRange : nMaxInspectRange; |
| | | int nInsRange = abs(nSideLineOffset_pxl) + abs(nInspect_Range_pxl); |
| | | nMaxInspectRange = (nMaxInspectRange < nInsRange) ? nInsRange : nMaxInspectRange; |
| | | } |
| | | } |
| | | rtFrame.InflateRect(nMaxInspectRange, 0); |
| | | |
| | | // 2. Make Roi, Exception Corner Area |
| | | CRect rtGlassSideROI; |
| | | rtGlassSideROI.left = 0; |
| | | rtGlassSideROI.top = (nTopCornerEndLine < nFindStartLine) ? nFindStartLine : nTopCornerEndLine; |
| | | rtGlassSideROI.right = m_nFrameWidth; |
| | | rtGlassSideROI.bottom = nBottomCornerStartLine; |
| | | rtGlassSideROI.left = 0; |
| | | rtGlassSideROI.top = (nTopCornerEndLine < nFindStartLine) ? nFindStartLine : nTopCornerEndLine; |
| | | rtGlassSideROI.right = m_nFrameWidth; |
| | | rtGlassSideROI.bottom = nBottomCornerStartLine; |
| | | |
| | | nCutLine = rtFrame.CenterPoint().x; |
| | | |
| | |
| | | CRect rtInspectArea; |
| | | rtInspectArea.IntersectRect(rtFrame, rtGlassSideROI); |
| | | |
| | | if(rtInspectArea.IsRectEmpty() || rtInspectArea.IsRectNull()) |
| | | if (rtInspectArea.IsRectEmpty() || rtInspectArea.IsRectNull()) |
| | | return FALSE; |
| | | |
| | | // 4. Exception Notch Area... |
| | |
| | | |
| | | std::vector<CRect> vectorInspectAreaList_Old; |
| | | vectorInspectAreaList_Old.clear(); |
| | | |
| | | |
| | | std::vector<CRect> vecExceptionNotchAreaList; |
| | | int nNotchCount = m_pRecipe->m_SideParam[(int) eDim].m_nNotchCount; |
| | | int nNotchCount = m_pRecipe->m_SideParam[(int)eDim].m_nNotchCount; |
| | | |
| | | for(int i=0; i<nNotchCount; i++) |
| | | for (int i = 0; i < nNotchCount; i++) |
| | | { |
| | | int nDiff_StartLine = nFindStartLine - m_pRecipe->m_SideParam[(int) eDim].m_NotchPrm[i].m_nGlassStartLine_pxl; |
| | | int nDiff_StartLine = nFindStartLine - m_pRecipe->m_SideParam[(int)eDim].m_NotchPrm[i].m_nGlassStartLine_pxl; |
| | | |
| | | CRect rtNotchArea = m_pRecipe->m_SideParam[(int) eDim].m_NotchPrm[i].m_rtNotch_Area_pxl; |
| | | CRect rtNotchArea = m_pRecipe->m_SideParam[(int)eDim].m_NotchPrm[i].m_rtNotch_Area_pxl; |
| | | |
| | | rtNotchArea.OffsetRect(0, nDiff_StartLine); |
| | | rtNotchArea.left = 0; |
| | | rtNotchArea.right = m_nFrameWidth; |
| | | |
| | | vectorInspectAreaList_Old.resize(vectorInspectAreaList_New.size()); |
| | | std::copy(vectorInspectAreaList_New.begin(), vectorInspectAreaList_New.end(), vectorInspectAreaList_Old.begin()); |
| | | std::copy(vectorInspectAreaList_New.begin(), vectorInspectAreaList_New.end(), vectorInspectAreaList_Old.begin()); |
| | | vectorInspectAreaList_New.clear(); |
| | | |
| | | for(int j=0; j<vectorInspectAreaList_Old.size(); j++) |
| | | for (int j = 0; j < vectorInspectAreaList_Old.size(); j++) |
| | | { |
| | | CRect rtTemp = vectorInspectAreaList_Old[j]; |
| | | |
| | | CRect rtNotchInterSectRect; |
| | | rtNotchInterSectRect.IntersectRect(rtTemp, rtNotchArea); |
| | | rtNotchInterSectRect.IntersectRect(rtTemp, rtNotchArea); |
| | | |
| | | if(rtNotchInterSectRect.IsRectEmpty() || rtNotchInterSectRect.IsRectNull()) // 畴摹啊 救吧府绰 版快俊绰 促矫 持绢霖促.. |
| | | if (rtNotchInterSectRect.IsRectEmpty() || rtNotchInterSectRect.IsRectNull()) // 노치가 안걸리는 경우에는 다시 넣어준다.. |
| | | { |
| | | vectorInspectAreaList_New.push_back(rtTemp); |
| | | continue; |
| | | } |
| | | |
| | | if(rtTemp.Height() == rtNotchInterSectRect.Height()) // Notch啊 康开狼 傈眉牢 版快 |
| | | if (rtTemp.Height() == rtNotchInterSectRect.Height()) // Notch가 영역의 전체인 경우 |
| | | continue; |
| | | |
| | | if(rtTemp.top == rtNotchInterSectRect.top && rtNotchInterSectRect.bottom < rtTemp.bottom) // 1. Notch Frame 困俊 吧赴 版快 |
| | | |
| | | if (rtTemp.top == rtNotchInterSectRect.top && rtNotchInterSectRect.bottom < rtTemp.bottom) // 1. Notch Frame 위에 걸린 경우 |
| | | { |
| | | CRect rtNew = rtTemp; |
| | | rtNew.top = rtNotchInterSectRect.bottom; |
| | | vectorInspectAreaList_New.push_back(rtNew); |
| | | } |
| | | else if(rtTemp.top < rtNotchInterSectRect.top && rtNotchInterSectRect.bottom < rtTemp.bottom) // 2. Notch Frame 吝埃俊 吧赴 版快 |
| | | else if (rtTemp.top < rtNotchInterSectRect.top && rtNotchInterSectRect.bottom < rtTemp.bottom) // 2. Notch Frame 중간에 걸린 경우 |
| | | { |
| | | CRect rtNewTop = rtTemp; |
| | | rtNewTop.top = rtNotchInterSectRect.bottom; |
| | |
| | | rtNewBot.bottom = rtNotchInterSectRect.top; |
| | | vectorInspectAreaList_New.push_back(rtNewBot); |
| | | } |
| | | else if(rtTemp.top < rtNotchInterSectRect.top && rtNotchInterSectRect.bottom == rtTemp.bottom) // 3. Notch Frame 酒贰俊 吧赴 版快 |
| | | else if (rtTemp.top < rtNotchInterSectRect.top && rtNotchInterSectRect.bottom == rtTemp.bottom) // 3. Notch Frame 아래에 걸린 경우 |
| | | { |
| | | CRect rtNew = rtTemp; |
| | | rtNew.bottom = rtNotchInterSectRect.top; |
| | |
| | | // 5. Make Return |
| | | vecInspectArea.clear(); |
| | | |
| | | for(int i=0; i<vectorInspectAreaList_New.size(); i++) |
| | | for (int i = 0; i < vectorInspectAreaList_New.size(); i++) |
| | | { |
| | | CRect rtInspectArea = vectorInspectAreaList_New[i]; |
| | | rtInspectArea.right = rtInspectArea.left + align_4byte(rtInspectArea.Width()); |
| | |
| | | return TRUE; |
| | | } |
| | | |
| | | BOOL CInspectCamera::InspectDefect_Process(int iThread,DimensionDir eDim,int iScan,int iFrame, CRect rtInspectArea, int nCutLine, eSideInsType emInsType, std::vector<CDefect_Info>* pDefectList) |
| | | BOOL CInspectCamera::InspectDefect_Process(int iThread, DimensionDir eDim, int iScan, int iFrame, CRect rtInspectArea, int nCutLine, eSideInsType emInsType, std::vector<CDefect_Info>* pDefectList) |
| | | { |
| | | if (rtInspectArea.IsRectEmpty() == TRUE || m_pGlassData == NULL) |
| | | return FALSE; |
| | | |
| | | int nSideLine = m_pGlassData->GetSideData(eDim)->m_nSideLineFrame[iFrame]; |
| | | int nSideLine = (int)m_pGlassData->GetSideData(eDim)->m_nSideLineFrame[iFrame]; |
| | | |
| | | if (nSideLine < 0) |
| | | return FALSE; |
| | | |
| | | DefectLocation defectLoc = DefectLoc_None; |
| | | |
| | | switch(emInsType) |
| | | switch (emInsType) |
| | | { |
| | | case eSideInsType_Chip: defectLoc = DefectLoc_Chip; |
| | | break; |
| | |
| | | return FALSE; |
| | | } |
| | | |
| | | if(m_pRecipe->m_SideParam[(int) eDim].m_InspectPrm[(int) emInsType].m_bUseInspect == FALSE) |
| | | if (m_pRecipe->m_SideParam[(int)eDim].m_InspectPrm[(int)emInsType].m_bUseInspect == FALSE) |
| | | return TRUE; |
| | | |
| | | // 0. Parameter Initialize.. |
| | | CString strDefectType = _T("Unknown"); |
| | | int nMethod = 0; |
| | | int nThreshold_Low = 0; |
| | | int nThreshold_High = 0; |
| | | int nPitch = 0; |
| | | int nPitch_Threshold = 0; |
| | | int nMinSize = 0; |
| | | int nMinSize_X = 0; |
| | | int nMinSize_Y = 0; |
| | | int nDilation = 0; |
| | | int nInsStart = 0; |
| | | int nInsRange = 0; |
| | | CString strDefectType = _T("Unknown"); |
| | | int nMethod = 0; |
| | | int nThreshold_Low = 0; |
| | | int nThreshold_High = 0; |
| | | int nPitch = 0; |
| | | int nPitch_Threshold = 0; |
| | | int nMinSize = 0; |
| | | int nMinSize_X = 0; |
| | | int nMinSize_Y = 0; |
| | | int nDilation = 0; |
| | | int nInsStart = 0; |
| | | int nInsRange = 0; |
| | | |
| | | BOOL bStartNearFilterUse = m_pRecipe->m_SideParam[(int) eDim].m_InspectPrm[(int) emInsType].m_bSide_Filter; |
| | | int nStartNearFilterRange = m_pRecipe->m_SideParam[(int) eDim].m_InspectPrm[(int) emInsType].m_nSide_Filter_um; |
| | | BOOL bStartNearFilterUse = m_pRecipe->m_SideParam[(int)eDim].m_InspectPrm[(int)emInsType].m_bSide_Filter; |
| | | int nStartNearFilterRange = m_pRecipe->m_SideParam[(int)eDim].m_InspectPrm[(int)emInsType].m_nSide_Filter_um; |
| | | |
| | | nMethod = m_pRecipe->m_SideParam[(int) eDim].m_InspectPrm[(int) emInsType].m_nInspect_Method; |
| | | nThreshold_Low = m_pRecipe->m_SideParam[(int) eDim].m_InspectPrm[(int) emInsType].m_nMin_Threshold; |
| | | nThreshold_High = m_pRecipe->m_SideParam[(int) eDim].m_InspectPrm[(int) emInsType].m_nMax_Threshold; |
| | | nPitch = m_pRecipe->m_SideParam[(int) eDim].m_InspectPrm[(int) emInsType].m_nDiff_Pitch; |
| | | nPitch_Threshold = m_pRecipe->m_SideParam[(int) eDim].m_InspectPrm[(int) emInsType].m_nDiff_Threshold; |
| | | nMinSize = m_pRecipe->m_SideParam[(int) eDim].m_InspectPrm[(int) emInsType].m_nMinSize_Filter_pxl; |
| | | nMinSize_X = (int) GetUmToPixel_X((double) m_pRecipe->m_SideParam[(int) eDim].m_InspectPrm[(int) emInsType].m_nMinSize_Filter_X_um); |
| | | nMinSize_Y = (int) GetUmToPixel_Y((double) m_pRecipe->m_SideParam[(int) eDim].m_InspectPrm[(int) emInsType].m_nMinSize_Filter_Y_um); |
| | | nDilation = m_pRecipe->m_SideParam[(int) eDim].m_InspectPrm[(int) emInsType].m_nDefect_Size_Dilation; |
| | | nMethod = m_pRecipe->m_SideParam[(int)eDim].m_InspectPrm[(int)emInsType].m_nInspect_Method; |
| | | nThreshold_Low = m_pRecipe->m_SideParam[(int)eDim].m_InspectPrm[(int)emInsType].m_nMin_Threshold; |
| | | nThreshold_High = m_pRecipe->m_SideParam[(int)eDim].m_InspectPrm[(int)emInsType].m_nMax_Threshold; |
| | | nPitch = m_pRecipe->m_SideParam[(int)eDim].m_InspectPrm[(int)emInsType].m_nDiff_Pitch; |
| | | nPitch_Threshold = m_pRecipe->m_SideParam[(int)eDim].m_InspectPrm[(int)emInsType].m_nDiff_Threshold; |
| | | nMinSize = m_pRecipe->m_SideParam[(int)eDim].m_InspectPrm[(int)emInsType].m_nMinSize_Filter_pxl; |
| | | nMinSize_X = (int)GetUmToPixel_X((double)m_pRecipe->m_SideParam[(int)eDim].m_InspectPrm[(int)emInsType].m_nMinSize_Filter_X_um); |
| | | nMinSize_Y = (int)GetUmToPixel_Y((double)m_pRecipe->m_SideParam[(int)eDim].m_InspectPrm[(int)emInsType].m_nMinSize_Filter_Y_um); |
| | | nDilation = m_pRecipe->m_SideParam[(int)eDim].m_InspectPrm[(int)emInsType].m_nDefect_Size_Dilation; |
| | | |
| | | nInsStart = (int) GetUmToPixel_X((double)m_pRecipe->m_SideParam[(int) eDim].m_InspectPrm[(int) emInsType].m_nInspect_SideLine_Offset_um); |
| | | nInsRange = (int) GetUmToPixel_X((double)m_pRecipe->m_SideParam[(int) eDim].m_InspectPrm[(int) emInsType].m_nInspect_Range_um); |
| | | nInsStart = (int)GetUmToPixel_X((double)m_pRecipe->m_SideParam[(int)eDim].m_InspectPrm[(int)emInsType].m_nInspect_SideLine_Offset_um); |
| | | nInsRange = (int)GetUmToPixel_X((double)m_pRecipe->m_SideParam[(int)eDim].m_InspectPrm[(int)emInsType].m_nInspect_Range_um); |
| | | |
| | | //CRect rtProcessArea(rtInspectArea.CenterPoint().x + nInsStart, rtInspectArea.top, rtInspectArea.CenterPoint().x + nInsStart + nInsRange, rtInspectArea.bottom); |
| | | CRect rtProcessArea(nCutLine + nInsStart, rtInspectArea.top, nCutLine + nInsStart + nInsRange, rtInspectArea.bottom); |
| | | |
| | | |
| | | |
| | | if (rtProcessArea.right < rtProcessArea.left) |
| | | { |
| | |
| | | return FALSE; |
| | | |
| | | CSISBuffer frameBuffer(m_pGrabber->GetFrameHeaderLine(iScan, rtInspectArea.top), m_nFrameWidth, m_nFrameHeight); |
| | | if(frameBuffer.IsValidBuffer() == FALSE) |
| | | if (frameBuffer.IsValidBuffer() == FALSE) |
| | | return FALSE; |
| | | |
| | | // Set Insert Area.. For UI.. |
| | | m_pGlassData->GetSideData(eDim)->m_rtInspectArea_InsType[(int) emInsType][iFrame] = rtProcessArea; |
| | | m_pGlassData->GetSideData(eDim)->m_rtInspectArea_InsType[(int)emInsType][iFrame] = rtProcessArea; |
| | | |
| | | if(bStartNearFilterUse) |
| | | m_pGlassData->GetSideData(eDim)->m_nSideFilterLine_InsType[(int) emInsType][iFrame] = (0 <= nStartNearFilterRange) ? rtProcessArea.left + nStartNearFilterRange : rtProcessArea.right + nStartNearFilterRange; |
| | | if (bStartNearFilterUse) |
| | | m_pGlassData->GetSideData(eDim)->m_nSideFilterLine_InsType[(int)emInsType][iFrame] = (0 <= nStartNearFilterRange) ? rtProcessArea.left + nStartNearFilterRange : rtProcessArea.right + nStartNearFilterRange; |
| | | |
| | | // 1. Inspect ROI |
| | | COwnerBuffer pDefectProcessImage(rtProcessArea.Width(), rtProcessArea.Height()); |
| | | |
| | | for (int i = 0; i < rtProcessArea.Height(); i++) |
| | | memcpy(pDefectProcessImage.GetDataAddress(0,i), frameBuffer.GetDataAddress(rtProcessArea.left, i), rtProcessArea.Width()); |
| | | memcpy(pDefectProcessImage.GetDataAddress(0, i), frameBuffer.GetDataAddress(rtProcessArea.left, i), rtProcessArea.Width()); |
| | | |
| | | // 2. Inspect Algorithm |
| | | COwnerBuffer pBinImage; |
| | |
| | | DefectProcess(eDim, iScan, iFrame, &pDefectProcessImage, &pBinImage, rtProcessArea, nMinSize, nMinSize_X, nMinSize_Y, nDilation, bStartNearFilterUse, nStartNearFilterRange, defectLoc, pDefectList); |
| | | |
| | | CString str; |
| | | str.Format(_T("Defect\\InsArea_Ori_Frame%d_%d_%d_%d_%d"),iFrame, rtInspectArea.left, rtInspectArea.top, rtInspectArea.right, rtInspectArea.bottom); |
| | | str.Format(_T("Defect\\InsArea_Ori_Frame%d_%d_%d_%d_%d"), iFrame, rtInspectArea.left, rtInspectArea.top, rtInspectArea.right, rtInspectArea.bottom); |
| | | SaveDebugImage(eDim, stFrameIndex(iScan, iFrame), &pDefectProcessImage, str); |
| | | |
| | | str.Format(_T("Defect\\InsArea_Bin_Frame%d_%d_%d_%d_%d"),iFrame, rtInspectArea.left, rtInspectArea.top, rtInspectArea.right, rtInspectArea.bottom); |
| | | str.Format(_T("Defect\\InsArea_Bin_Frame%d_%d_%d_%d_%d"), iFrame, rtInspectArea.left, rtInspectArea.top, rtInspectArea.right, rtInspectArea.bottom); |
| | | SaveDebugImage(eDim, stFrameIndex(iScan, iFrame), &pBinImage, str); |
| | | |
| | | return TRUE; |
| | |
| | | { |
| | | if (compareResult.m128i_u8[k] != 0) |
| | | { |
| | | pBinImage->SetPixel(j+k, i, 255); //[i * pBinImage->step1() + j + k] = (char)255; |
| | | pBinImage->SetPixel(j + k, i, 255); //[i * pBinImage->step1() + j + k] = (char)255; |
| | | } |
| | | } |
| | | } |
| | |
| | | { |
| | | if (compareResult.m128i_u8[k] != 0) |
| | | { |
| | | pBinImage->SetPixel(j+k, i, 255); // [i * pBinImage->step1() + j + k] = (char)255; |
| | | pBinImage->SetPixel(j + k, i, 255); // [i * pBinImage->step1() + j + k] = (char)255; |
| | | } |
| | | } |
| | | } |
| | |
| | | { |
| | | if (compareResult.m128i_u8[k] != 0) |
| | | { |
| | | pBinImage->SetPixel(j+k, i, 255); // [i * pBinImage->step1() + j + k] = (char)255; |
| | | pBinImage->SetPixel(j + k, i, 255); // [i * pBinImage->step1() + j + k] = (char)255; |
| | | } |
| | | } |
| | | } |
| | |
| | | } |
| | | |
| | | // 2. Threshold Suppress |
| | | compare_Thres_Low = _mm_andnot_si128(_mm_cmpeq_epi8(_mm_min_epu8(imageSource, thresLow), thresLow), K_INV_ZERO); // Greater Than |
| | | compare_Thres_High = _mm_andnot_si128(_mm_cmpeq_epi8(_mm_max_epu8(imageSource, thresHigh), thresHigh), K_INV_ZERO); // Less Than |
| | | compare_Thres_Result = _mm_or_si128(compare_Thres_Low, compare_Thres_High); |
| | | compare_Thres_Low = _mm_andnot_si128(_mm_cmpeq_epi8(_mm_min_epu8(imageSource, thresLow), thresLow), K_INV_ZERO); // Greater Than |
| | | compare_Thres_High = _mm_andnot_si128(_mm_cmpeq_epi8(_mm_max_epu8(imageSource, thresHigh), thresHigh), K_INV_ZERO); // Less Than |
| | | compare_Thres_Result = _mm_or_si128(compare_Thres_Low, compare_Thres_High); |
| | | |
| | | // 3. Pitch Compare |
| | | compare_Pitch_Up = _mm_abs_epi8(_mm_sub_epi8(imageSource, imageSource_Up)); |
| | | compare_Pitch_Down = _mm_abs_epi8(_mm_sub_epi8(imageSource, imageSource_Down)); // Less Than |
| | | compare_Pitch_Up = _mm_abs_epi8(_mm_sub_epi8(imageSource, imageSource_Up)); |
| | | compare_Pitch_Down = _mm_abs_epi8(_mm_sub_epi8(imageSource, imageSource_Down)); // Less Than |
| | | //compare_Pitch_Result = _mm_min_epu8(compare_Pitch_Up, compare_Pitch_Down); |
| | | compare_Pitch_Result = _mm_max_epu8(compare_Pitch_Up, compare_Pitch_Down); |
| | | compare_Pitch_Result = _mm_andnot_si128(_mm_cmpeq_epi8(_mm_max_epu8(compare_Pitch_Result, thresPitch), thresPitch), K_INV_ZERO); // Less Than |
| | | compare_Pitch_Result = _mm_max_epu8(compare_Pitch_Up, compare_Pitch_Down); |
| | | compare_Pitch_Result = _mm_andnot_si128(_mm_cmpeq_epi8(_mm_max_epu8(compare_Pitch_Result, thresPitch), thresPitch), K_INV_ZERO); // Less Than |
| | | |
| | | // 4. And |
| | | compare_Result = _mm_and_si128(compare_Thres_Result, compare_Pitch_Result); |
| | | compare_Result = _mm_and_si128(compare_Thres_Result, compare_Pitch_Result); |
| | | |
| | | int nProcCount = (pImageData->GetWidth() - (16 * nMul)); |
| | | |
| | |
| | | { |
| | | if (compare_Result.m128i_u8[k] != 0) |
| | | { |
| | | pBinImage->SetPixel(j+k, i, 255); //[i * pBinImage->GetWidth() + j + k] = (char)255; |
| | | pBinImage->SetPixel(j + k, i, 255); //[i * pBinImage->GetWidth() + j + k] = (char)255; |
| | | } |
| | | } |
| | | } |
| | |
| | | } |
| | | |
| | | // 2. Threshold Suppress |
| | | compare_Thres_Low = _mm_andnot_si128(_mm_cmpeq_epi8(_mm_min_epu8(imageSource, thresLow), thresLow), K_INV_ZERO); // Greater Than |
| | | compare_Thres_High = _mm_andnot_si128(_mm_cmpeq_epi8(_mm_max_epu8(imageSource, thresHigh), thresHigh), K_INV_ZERO); // Less Than |
| | | compare_Thres_Result = _mm_or_si128(compare_Thres_Low, compare_Thres_High); |
| | | compare_Thres_Low = _mm_andnot_si128(_mm_cmpeq_epi8(_mm_min_epu8(imageSource, thresLow), thresLow), K_INV_ZERO); // Greater Than |
| | | compare_Thres_High = _mm_andnot_si128(_mm_cmpeq_epi8(_mm_max_epu8(imageSource, thresHigh), thresHigh), K_INV_ZERO); // Less Than |
| | | compare_Thres_Result = _mm_or_si128(compare_Thres_Low, compare_Thres_High); |
| | | |
| | | // 3. Pitch Compare |
| | | compare_Pitch_Up = _mm_abs_epi8(_mm_sub_epi8(imageSource, imageSource_Up)); |
| | | compare_Pitch_Down = _mm_abs_epi8(_mm_sub_epi8(imageSource, imageSource_Down)); // Less Than |
| | | compare_Pitch_Up = _mm_abs_epi8(_mm_sub_epi8(imageSource, imageSource_Up)); |
| | | compare_Pitch_Down = _mm_abs_epi8(_mm_sub_epi8(imageSource, imageSource_Down)); // Less Than |
| | | //compare_Pitch_Result = _mm_min_epu8(compare_Pitch_Up, compare_Pitch_Down); |
| | | compare_Pitch_Result = _mm_max_epu8(compare_Pitch_Up, compare_Pitch_Down); |
| | | compare_Pitch_Result = _mm_andnot_si128(_mm_cmpeq_epi8(_mm_max_epu8(compare_Pitch_Result, thresPitch), thresPitch), K_INV_ZERO); // Less Than |
| | | compare_Pitch_Result = _mm_max_epu8(compare_Pitch_Up, compare_Pitch_Down); |
| | | compare_Pitch_Result = _mm_andnot_si128(_mm_cmpeq_epi8(_mm_max_epu8(compare_Pitch_Result, thresPitch), thresPitch), K_INV_ZERO); // Less Than |
| | | |
| | | // 4. And |
| | | compare_Result = _mm_and_si128(compare_Thres_Result, compare_Pitch_Result); |
| | | compare_Result = _mm_and_si128(compare_Thres_Result, compare_Pitch_Result); |
| | | |
| | | int nProcCount = (pImageData->GetWidth() - (16 * nMul)); |
| | | |
| | |
| | | { |
| | | if (compare_Result.m128i_u8[k] != 0) |
| | | { |
| | | pBinImage->SetPixel(j+k, i, 255); //[i * pBinImage->GetWidth() + j + k] = (char)255; |
| | | pBinImage->SetPixel(j + k, i, 255); //[i * pBinImage->GetWidth() + j + k] = (char)255; |
| | | } |
| | | } |
| | | } |
| | |
| | | |
| | | static int g_static_debug = 1; |
| | | |
| | | BOOL CInspectCamera::DefectProcess(DimensionDir eDim,int iScan,int iFrame, COwnerBuffer* pImageData, COwnerBuffer* pBinImage, CRect rtROIPos, int nMinSize, int nMinSizeX, int nMinSizeY, int nDilation, BOOL bStartNearFilter, int nStartNearFilterRange, DefectLocation defectType, std::vector<CDefect_Info>* pDefectList) |
| | | BOOL CInspectCamera::DefectProcess(DimensionDir eDim, int iScan, int iFrame, COwnerBuffer* pImageData, COwnerBuffer* pBinImage, CRect rtROIPos, int nMinSize, int nMinSizeX, int nMinSizeY, int nDilation, BOOL bStartNearFilter, int nStartNearFilterRange, DefectLocation defectType, std::vector<CDefect_Info>* pDefectList) |
| | | { |
| | | if(pDefectList == NULL) |
| | | if (pDefectList == NULL) |
| | | return FALSE; |
| | | |
| | | if (pImageData == NULL || pBinImage == NULL) |
| | |
| | | |
| | | cv::Mat pBinMat = cv::Mat::zeros(pBinImage->GetHeight(), pBinImage->GetWidth(), CV_8UC1); |
| | | |
| | | // OwnerBuffer 郴何肺 16硅荐 皋葛府 爱绊 乐绢辑 茄锅俊 墨乔 救蹬.. |
| | | for(int i=0; i<pBinImage->GetHeight(); i++) |
| | | // OwnerBuffer 내부로 16배수 메모리 갖고 있어서 한번에 카피 안돼.. |
| | | for (int i = 0; i < pBinImage->GetHeight(); i++) |
| | | CopyMemory(&pBinMat.data[pBinMat.step1() * i], pBinImage->GetDataAddress(0, i), pBinImage->GetWidth()); |
| | | |
| | | /* |
| | |
| | | // cv::dilate(pBinMat, pBinMat, cv::getStructuringElement(cv::MORPH_ELLIPSE, cv::Size(3, 3)), cv::Point(-1,-1), nDilation); |
| | | |
| | | CString strFileName; |
| | | strFileName.Format(_T("Defect\\%s_Origin"), g_strDefectType[(int) defectType]); |
| | | strFileName.Format(_T("Defect\\%s_Origin"), g_strDefectType[(int)defectType]); |
| | | SaveDebugImage(eDim, stFrameIndex(iScan, iFrame), pImageData, strFileName); |
| | | |
| | | strFileName.Format(_T("Defect\\%s_Bin"), g_strDefectType[(int) defectType]); |
| | | strFileName.Format(_T("Defect\\%s_Bin"), g_strDefectType[(int)defectType]); |
| | | SaveDebugImage(eDim, stFrameIndex(iScan, iFrame), pBinImage, strFileName); |
| | | |
| | | cv::Mat matLabel, matStats, matCentrois; |
| | | |
| | | int numOfLables = cv::connectedComponentsWithStats(pBinMat, matLabel, matStats, matCentrois, 8); |
| | | |
| | | if(numOfLables <= 1) // 硅版 窍唱父 乐澜.. |
| | | if (numOfLables <= 1) // 배경 하나만 있음.. |
| | | return TRUE; |
| | | |
| | | std::vector<int> vecMin, vecMax, vecSum, vecPixelCount; |
| | |
| | | |
| | | int nPxlValue = (int)pImageData->GetPixel(j, i); |
| | | |
| | | if(nLabelIdx == 0) |
| | | if (nLabelIdx == 0) |
| | | continue; |
| | | if(pBinImage->GetPixel(j, i) == 0 && nLabelIdx < MAX_DEFECT_COUNT_SIDE) |
| | | if (pBinImage->GetPixel(j, i) == 0 && nLabelIdx < MAX_DEFECT_COUNT_SIDE) |
| | | backgroundLables[nLabelIdx] = TRUE; |
| | | |
| | | if (nPxlValue < vecMin[nLabelIdx]) |
| | |
| | | } |
| | | } |
| | | |
| | | int nDefectIdx = (int) pDefectList->size(); |
| | | int nDefectIdx = (int)pDefectList->size(); |
| | | |
| | | for (int nIdx = 0; nIdx < numOfLables; nIdx++) |
| | | { |
| | |
| | | int width = matStats.at<int>(nIdx, cv::CC_STAT_WIDTH); |
| | | int height = matStats.at<int>(nIdx, cv::CC_STAT_HEIGHT); |
| | | |
| | | int x = (int)matCentrois.at<double>(nIdx, 0); //吝缴谅钎 |
| | | int x = (int)matCentrois.at<double>(nIdx, 0); //중심좌표 |
| | | int y = (int)matCentrois.at<double>(nIdx, 1); |
| | | |
| | | if(MAX_DEFECT_COUNT_SIDE < nIdx) |
| | | if (MAX_DEFECT_COUNT_SIDE < nIdx) |
| | | continue; |
| | | |
| | | if(backgroundLables[nIdx] == TRUE) |
| | | if (backgroundLables[nIdx] == TRUE) |
| | | continue; |
| | | |
| | | if(nIdx == 0) |
| | | if (nIdx == 0) |
| | | continue; |
| | | |
| | | if ((0 < nStartNearFilterRange && left <= nStartNearFilterRange) || (nStartNearFilterRange < 0 && pBinImage->GetWidth() + nStartNearFilterRange <= left + width)) |
| | |
| | | if (vecPixelCount[nIdx] < nMinSize) |
| | | bFiltering = TRUE; |
| | | |
| | | if(width < nMinSizeX) |
| | | if (width < nMinSizeX) |
| | | bFiltering = TRUE; |
| | | |
| | | if(height < nMinSizeY) |
| | | if (height < nMinSizeY) |
| | | bFiltering = TRUE; |
| | | |
| | | if (bStartNearFilter == TRUE && bStartNear == FALSE) |
| | |
| | | |
| | | CDefect_Info defectInfo; |
| | | |
| | | defectInfo.m_nIndex = nDefectIdx++; |
| | | defectInfo.m_iFrameIdx = iFrame; |
| | | defectInfo.m_nCamID = m_iCamera; |
| | | defectInfo.m_nScanIdx = iScan; |
| | | defectInfo.m_nGlassStartLine = m_pGlassData->GetSideData(eDim)->m_nGlassStartLine; |
| | | defectInfo.m_nSideIdx = (int) eDim; |
| | | defectInfo.m_nIndex = nDefectIdx++; |
| | | defectInfo.m_iFrameIdx = iFrame; |
| | | defectInfo.m_nCamID = m_iCamera; |
| | | defectInfo.m_nScanIdx = iScan; |
| | | defectInfo.m_nGlassStartLine = m_pGlassData->GetSideData(eDim)->m_nGlassStartLine; |
| | | defectInfo.m_nSideIdx = (int)eDim; |
| | | |
| | | defectInfo.m_ptDefectPos_pxl = rtDefectArea.CenterPoint(); |
| | | defectInfo.m_rtDefectPos_pxl = rtDefectArea; |
| | | defectInfo.m_ptDefectPos_pxl = rtDefectArea.CenterPoint(); |
| | | defectInfo.m_rtDefectPos_pxl = rtDefectArea; |
| | | |
| | | defectInfo.m_nMinSize = nMinSize; |
| | | defectInfo.m_nBlobDilation = area; |
| | | defectInfo.m_nMinSize = nMinSize; |
| | | defectInfo.m_nBlobDilation = area; |
| | | |
| | | // Image Info |
| | | defectInfo.m_nBlobCount = vecPixelCount[nIdx]; |
| | | defectInfo.m_nGray_Max = vecMax[nIdx]; |
| | | defectInfo.m_nGray_Min = vecMin[nIdx]; |
| | | defectInfo.m_nGray_Sum = vecSum[nIdx]; |
| | | defectInfo.m_dGray_Avg = (double)(defectInfo.m_nGray_Sum) / (double)(defectInfo.m_nBlobCount); |
| | | defectInfo.m_dRectArea_Ratio = 100.0 * ((double) defectInfo.m_nBlobCount) / ((double) (rtDefectArea.Width() * rtDefectArea.Height())); |
| | | defectInfo.m_DefectLoc = defectType; |
| | | defectInfo.m_nBlobCount = vecPixelCount[nIdx]; |
| | | defectInfo.m_nGray_Max = vecMax[nIdx]; |
| | | defectInfo.m_nGray_Min = vecMin[nIdx]; |
| | | defectInfo.m_nGray_Sum = vecSum[nIdx]; |
| | | defectInfo.m_dGray_Avg = (double)(defectInfo.m_nGray_Sum) / (double)(defectInfo.m_nBlobCount); |
| | | defectInfo.m_dRectArea_Ratio = 100.0 * ((double)defectInfo.m_nBlobCount) / ((double)(rtDefectArea.Width() * rtDefectArea.Height())); |
| | | defectInfo.m_DefectLoc = defectType; |
| | | |
| | | pDefectList->push_back(defectInfo); |
| | | } |
| | |
| | | return TRUE; |
| | | } |
| | | |
| | | BOOL CInspectCamera::DefectProcess(DimensionDir eDim,int iScan,int iFrame, IplImage* pImageData, IplImage* pBinImage, CRect rtROIPos, int nMinSize, int nMinSizeX, int nMinSizeY, int nDilation, BOOL bStartNearFilter, int nStartNearFilterRange, DefectLocation defectType, std::vector<CDefect_Info>* pDefectList) |
| | | BOOL CInspectCamera::DefectProcess(DimensionDir eDim, int iScan, int iFrame, IplImage* pImageData, IplImage* pBinImage, CRect rtROIPos, int nMinSize, int nMinSizeX, int nMinSizeY, int nDilation, BOOL bStartNearFilter, int nStartNearFilterRange, DefectLocation defectType, std::vector<CDefect_Info>* pDefectList) |
| | | { |
| | | if(pDefectList == NULL) |
| | | if (pDefectList == NULL) |
| | | return FALSE; |
| | | |
| | | if (pImageData == NULL || pBinImage == NULL) |
| | |
| | | |
| | | cv::Mat pBinMat = cv::Mat::zeros(pBinImage->height, pBinImage->width, CV_8UC1); |
| | | |
| | | // OwnerBuffer 郴何肺 16硅荐 皋葛府 爱绊 乐绢辑 茄锅俊 墨乔 救蹬.. |
| | | for(int i=0; i<pBinImage->height; i++) |
| | | CopyMemory(&pBinMat.data[pBinMat.step1() * i], &pBinImage->imageData[pBinImage->widthStep*i], pBinImage->width); |
| | | // OwnerBuffer 내부로 16배수 메모리 갖고 있어서 한번에 카피 안돼.. |
| | | for (int i = 0; i < pBinImage->height; i++) |
| | | CopyMemory(&pBinMat.data[pBinMat.step1() * i], &pBinImage->imageData[pBinImage->widthStep * i], pBinImage->width); |
| | | |
| | | /* |
| | | if(0 < nDilation) |
| | |
| | | // cv::dilate(pBinMat, pBinMat, cv::getStructuringElement(cv::MORPH_ELLIPSE, cv::Size(3, 3)), cv::Point(-1,-1), nDilation); |
| | | |
| | | CString strFileName; |
| | | strFileName.Format(_T("Defect\\%s_Origin"), g_strDefectType[(int) defectType]); |
| | | strFileName.Format(_T("Defect\\%s_Origin"), g_strDefectType[(int)defectType]); |
| | | SaveDebugImage(eDim, stFrameIndex(iScan, iFrame), pImageData, strFileName); |
| | | |
| | | strFileName.Format(_T("Defect\\%s_Bin"), g_strDefectType[(int) defectType]); |
| | | strFileName.Format(_T("Defect\\%s_Bin"), g_strDefectType[(int)defectType]); |
| | | SaveDebugImage(eDim, stFrameIndex(iScan, iFrame), pBinImage, strFileName); |
| | | |
| | | cv::Mat matLabel, matStats, matCentrois; |
| | | |
| | | int numOfLables = cv::connectedComponentsWithStats(pBinMat, matLabel, matStats, matCentrois, 8); |
| | | |
| | | if(numOfLables <= 1) // 硅版 窍唱父 乐澜.. |
| | | if (numOfLables <= 1) // 배경 하나만 있음.. |
| | | return TRUE; |
| | | |
| | | std::vector<int> vecMin, vecMax, vecSum, vecPixelCount; |
| | |
| | | { |
| | | int nLabelIdx = (int)label[j]; |
| | | |
| | | int nPxlValue = (int)pImageData->imageData[i*pImageData->widthStep+j]; |
| | | int nPxlValue = (int)pImageData->imageData[i * pImageData->widthStep + j]; |
| | | |
| | | if(nLabelIdx == 0) |
| | | if (nLabelIdx == 0) |
| | | continue; |
| | | if(pBinImage->imageData[i*pImageData->widthStep+j] == 0 && nLabelIdx < MAX_DEFECT_COUNT_SIDE) |
| | | if (pBinImage->imageData[i * pImageData->widthStep + j] == 0 && nLabelIdx < MAX_DEFECT_COUNT_SIDE) |
| | | backgroundLables[nLabelIdx] = TRUE; |
| | | |
| | | if (nPxlValue < vecMin[nLabelIdx]) |
| | |
| | | } |
| | | } |
| | | |
| | | int nDefectIdx = (int) pDefectList->size(); |
| | | int nDefectIdx = (int)pDefectList->size(); |
| | | |
| | | for (int nIdx = 0; nIdx < numOfLables; nIdx++) |
| | | { |
| | |
| | | int width = matStats.at<int>(nIdx, cv::CC_STAT_WIDTH); |
| | | int height = matStats.at<int>(nIdx, cv::CC_STAT_HEIGHT); |
| | | |
| | | int x = (int)matCentrois.at<double>(nIdx, 0); //吝缴谅钎 |
| | | int x = (int)matCentrois.at<double>(nIdx, 0); //중심좌표 |
| | | int y = (int)matCentrois.at<double>(nIdx, 1); |
| | | |
| | | if(MAX_DEFECT_COUNT_SIDE < nIdx) |
| | | if (MAX_DEFECT_COUNT_SIDE < nIdx) |
| | | continue; |
| | | |
| | | if(backgroundLables[nIdx] == TRUE) |
| | | if (backgroundLables[nIdx] == TRUE) |
| | | continue; |
| | | |
| | | if(nIdx == 0) |
| | | if (nIdx == 0) |
| | | continue; |
| | | |
| | | if ((0 < nStartNearFilterRange && left <= nStartNearFilterRange) || (nStartNearFilterRange < 0 && pBinImage->width + nStartNearFilterRange <= left + width)) |
| | |
| | | |
| | | if (nMinSizeX != 0) |
| | | { |
| | | if(width < nMinSizeX) |
| | | bFiltering = TRUE; |
| | | if (width < nMinSizeX) |
| | | bFiltering = TRUE; |
| | | } |
| | | if (nMinSizeY!= 0) |
| | | if (nMinSizeY != 0) |
| | | { |
| | | if (height < nMinSizeY) |
| | | bFiltering = TRUE; |
| | | } |
| | | |
| | | |
| | | |
| | | if (bStartNearFilter == TRUE && bStartNear == FALSE) |
| | | bFiltering = TRUE; |
| | |
| | | |
| | | CDefect_Info defectInfo; |
| | | |
| | | defectInfo.m_nIndex = nDefectIdx++; |
| | | defectInfo.m_iFrameIdx = iFrame; |
| | | defectInfo.m_nCamID = m_iCamera; |
| | | defectInfo.m_nScanIdx = iScan; |
| | | defectInfo.m_nGlassStartLine = m_pGlassData->GetSideData(eDim)->m_nGlassStartLine; |
| | | defectInfo.m_nSideIdx = (int) eDim; |
| | | defectInfo.m_nIndex = nDefectIdx++; |
| | | defectInfo.m_iFrameIdx = iFrame; |
| | | defectInfo.m_nCamID = m_iCamera; |
| | | defectInfo.m_nScanIdx = iScan; |
| | | defectInfo.m_nGlassStartLine = m_pGlassData->GetSideData(eDim)->m_nGlassStartLine; |
| | | defectInfo.m_nSideIdx = (int)eDim; |
| | | |
| | | defectInfo.m_ptDefectPos_pxl = rtDefectArea.CenterPoint(); |
| | | defectInfo.m_rtDefectPos_pxl = rtDefectArea; |
| | | defectInfo.m_ptDefectPos_pxl = rtDefectArea.CenterPoint(); |
| | | defectInfo.m_rtDefectPos_pxl = rtDefectArea; |
| | | |
| | | defectInfo.m_nMinSize = nMinSize; |
| | | defectInfo.m_nBlobDilation = area; |
| | | defectInfo.m_nMinSize = nMinSize; |
| | | defectInfo.m_nBlobDilation = area; |
| | | |
| | | // Image Info |
| | | defectInfo.m_nBlobCount = vecPixelCount[nIdx]; |
| | | defectInfo.m_nGray_Max = vecMax[nIdx]; |
| | | defectInfo.m_nGray_Min = vecMin[nIdx]; |
| | | defectInfo.m_nGray_Sum = vecSum[nIdx]; |
| | | defectInfo.m_dGray_Avg = (double)(defectInfo.m_nGray_Sum) / (double)(defectInfo.m_nBlobCount); |
| | | defectInfo.m_dRectArea_Ratio = 100.0 * ((double) defectInfo.m_nBlobCount) / ((double) (rtDefectArea.Width() * rtDefectArea.Height())); |
| | | defectInfo.m_DefectLoc = defectType; |
| | | defectInfo.m_nBlobCount = vecPixelCount[nIdx]; |
| | | defectInfo.m_nGray_Max = vecMax[nIdx]; |
| | | defectInfo.m_nGray_Min = vecMin[nIdx]; |
| | | defectInfo.m_nGray_Sum = vecSum[nIdx]; |
| | | defectInfo.m_dGray_Avg = (double)(defectInfo.m_nGray_Sum) / (double)(defectInfo.m_nBlobCount); |
| | | defectInfo.m_dRectArea_Ratio = 100.0 * ((double)defectInfo.m_nBlobCount) / ((double)(rtDefectArea.Width() * rtDefectArea.Height())); |
| | | defectInfo.m_DefectLoc = defectType; |
| | | |
| | | pDefectList->push_back(defectInfo); |
| | | } |
| | |
| | | return TRUE; |
| | | } |
| | | |
| | | BOOL CInspectCamera::Notch_Process(int iThread,DimensionDir emDim, stFrameIndex stFrame) |
| | | BOOL CInspectCamera::Notch_Process(int iThread, DimensionDir emDim, stFrameIndex stFrame) |
| | | { |
| | | if(m_pGlassData == NULL) |
| | | if (m_pGlassData == NULL) |
| | | return FALSE; |
| | | |
| | | CSide_Data* pSideData = m_pGlassData->GetSideData(emDim); |
| | | CSide_Data* pSideData = m_pGlassData->GetSideData(emDim); |
| | | |
| | | if(pSideData == NULL) |
| | | if (pSideData == NULL) |
| | | return FALSE; |
| | | |
| | | if(pSideData->m_bFindGlassEndLine == FALSE) // Notch Processing篮 End Line 茫篮 Frame捞.. |
| | | if (pSideData->m_bFindGlassEndLine == FALSE) // Notch Processing은 End Line 찾은 Frame이.. |
| | | return FALSE; |
| | | |
| | | if(m_pRecipe == NULL) |
| | | if (m_pRecipe == NULL) |
| | | return FALSE; |
| | | |
| | | if(m_pDefectControl == NULL) |
| | | if (m_pDefectControl == NULL) |
| | | return FALSE; |
| | | |
| | | if(pSideData->m_bNotchInspection_Complete == TRUE) |
| | | if (pSideData->m_bNotchInspection_Complete == TRUE) |
| | | return TRUE; |
| | | |
| | | int nNotchCount = m_pRecipe->m_SideParam[(int) emDim].m_nNotchCount; |
| | | int nNotchCount = m_pRecipe->m_SideParam[(int)emDim].m_nNotchCount; |
| | | |
| | | g_pLog->DisplayMessage(_T("Notch_Process %s : %d, count %d"),g_SideName[(int) emDim], stFrame.nFrameIdx,nNotchCount); |
| | | g_pLog->DisplayMessage(_T("Notch_Process %s : %d, count %d"), g_SideName[(int)emDim], stFrame.nFrameIdx, nNotchCount); |
| | | |
| | | pSideData->m_nNotchCount = nNotchCount; |
| | | |
| | | for(int i=0; i<nNotchCount; i++) |
| | | for (int i = 0; i < nNotchCount; i++) |
| | | { |
| | | if(m_pRecipe->m_SideParam[(int) emDim].m_NotchPrm[i].m_bNotch_Use == FALSE) |
| | | if (m_pRecipe->m_SideParam[(int)emDim].m_NotchPrm[i].m_bNotch_Use == FALSE) |
| | | continue; |
| | | |
| | | CPoint ptSet_TopMark = m_pRecipe->m_SideParam[(int) emDim].m_NotchPrm[i].m_ptTopMarkPos; |
| | | CPoint ptSet_BotMark = m_pRecipe->m_SideParam[(int) emDim].m_NotchPrm[i].m_ptBotMarkPos; |
| | | CRect rtSet_Area = m_pRecipe->m_SideParam[(int) emDim].m_NotchPrm[i].m_rtNotch_Area_pxl; |
| | | CPoint ptSet_TopMark = m_pRecipe->m_SideParam[(int)emDim].m_NotchPrm[i].m_ptTopMarkPos; |
| | | CPoint ptSet_BotMark = m_pRecipe->m_SideParam[(int)emDim].m_NotchPrm[i].m_ptBotMarkPos; |
| | | CRect rtSet_Area = m_pRecipe->m_SideParam[(int)emDim].m_NotchPrm[i].m_rtNotch_Area_pxl; |
| | | |
| | | CRect rtRotateArea; |
| | | CRect rtNotchAreaTemp; |
| | | if(GetAlignRotate(emDim, ptSet_TopMark, ptSet_BotMark, rtSet_Area, rtRotateArea) == FALSE) |
| | | if (GetAlignRotate(emDim, ptSet_TopMark, ptSet_BotMark, rtSet_Area, rtRotateArea) == FALSE) |
| | | continue; |
| | | |
| | | g_pLog->DisplayMessage(_T("Notch_Process %s : %d, idx %d - %d,%d,%d,%d"),g_SideName[(int) emDim], stFrame.nFrameIdx,i,rtRotateArea.left,rtRotateArea.top,rtRotateArea.right,rtRotateArea.bottom); |
| | | |
| | | g_pLog->DisplayMessage(_T("Notch_Process %s : %d, idx %d - %d,%d,%d,%d"), g_SideName[(int)emDim], stFrame.nFrameIdx, i, rtRotateArea.left, rtRotateArea.top, rtRotateArea.right, rtRotateArea.bottom); |
| | | |
| | | pSideData->m_rtNotchArea_pxl[i] = rtRotateArea; |
| | | //屏蔽Notch 区域上下位置 |
| | | //팁귁Notch 혐堵 龜쫍뿟? |
| | | rtRotateArea.top += 15; |
| | | rtRotateArea.bottom -= 15; |
| | | IplImage* pOriginImage; |
| | | IplImage* pEdgeImage; |
| | | IplImage* pBinImage; |
| | | |
| | | pOriginImage = cvCreateImageHeader(cvSize(m_nFrameWidth, rtRotateArea.Height()),8,1); |
| | | pOriginImage = cvCreateImageHeader(cvSize(m_nFrameWidth, rtRotateArea.Height()), 8, 1); |
| | | cvSetData(pOriginImage, m_pGrabber->GetFrameHeaderLine(stFrame.nScanIdx, rtRotateArea.top), IMAGE_WIDTH); |
| | | pEdgeImage = cvCloneImage(pOriginImage); |
| | | pBinImage = cvCloneImage(pOriginImage); |
| | |
| | | defectInfo.m_nSideIdx = (int)emDim; |
| | | defectInfo.m_ptDefectPos_pxl = rtRotateArea.CenterPoint(); |
| | | defectInfo.m_rtDefectPos_pxl = rtRotateArea; |
| | | defectInfo.m_DefectLoc = DefectLoc_Notch_Crack; |
| | | defectInfo.m_DefectLoc = DefectLoc_Notch_NoGrind; |
| | | m_pDefectControl->ExtractDefect(emDim, m_iCamera, stFrame.nScanIdx, defectInfo); |
| | | |
| | | cvReleaseImageHeader(&pOriginImage); |
| | |
| | | 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); |
| | | g_pLog->DisplayMessage(_T("7. Notch_Process %s : %d, idx %d"), g_SideName[(int)emDim], stFrame.nFrameIdx, i); |
| | | cvReleaseImageHeader(&pOriginImage); |
| | | cvReleaseImage(&pEdgeImage); |
| | | cvReleaseImage(&pBinImage); |
| | |
| | | return; |
| | | } |
| | | |
| | | // 中值滤波器大小,用于去噪,必须为奇数(若偶数会自动减1) |
| | | // 櫓令쫀꺼포댕鬼,痰黨혼臀,극伎槨펜鑒(흼탉鑒삔菱땡숑1) |
| | | const int nSmoothFilter = m_pRecipe->m_SideParam[(int)emDim].m_NotchPrm[nNotchIdx].m_nSmooth_Filter; |
| | | |
| | | // 磨边区域阈值,控制反二值化阈值,主要用于提取 Notch 边缘特征 |
| | | // 칠긋혐堵埴令,왠齡럽랗令뺏埴令,寮狼痰黨瓊혤 Notch 긋鍍景瀝 |
| | | const int nGrindThreshold = m_pRecipe->m_SideParam[(int)emDim].m_NotchPrm[nNotchIdx].m_nGrind_Threshold; |
| | | |
| | | // 玻璃区域阈值,控制正二值化阈值,用于提取玻璃主体区域 |
| | | // 깼젝혐堵埴令,왠齡攣랗令뺏埴令,痰黨瓊혤깼젝寮竟혐堵 |
| | | const int nGlassThreshold = m_pRecipe->m_SideParam[(int)emDim].m_NotchPrm[nNotchIdx].m_nGlass_Threshold; |
| | | |
| | | // 确保奇数滤波器大小 |
| | | // 횅괏펜鑒쫀꺼포댕鬼 |
| | | int nFilterSize = (nSmoothFilter % 2 == 0) ? (nSmoothFilter - 1) : nSmoothFilter; |
| | | |
| | | if (nFilterSize > 1) { |
| | | // 中值滤波降噪 |
| | | // 櫓令쫀꺼슉臀 |
| | | cvSmooth(scr, img_Bin, CV_MEDIAN, nFilterSize); |
| | | } |
| | | |
| | | // Edge图:反二值化阈值处理 |
| | | // 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); |
| | | |
| | | // Bin图:正常二值化 |
| | | // 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) |
| | | void CInspectCamera::Notch_Process_Measure(DimensionDir emDim, stFrameIndex stFrame, int nNotchIdx, IplImage* scr, IplImage* img_Edge, IplImage* img_Bin, CRect rtROI) |
| | | { |
| | | if(m_pRecipe == NULL) |
| | | if (m_pRecipe == NULL) |
| | | return; |
| | | |
| | | double dPixelSizeX = m_dPixelSizeX; |
| | |
| | | IplImage* img_Find_MeasureLine; |
| | | IplImage* img_Result = cvCloneImage(scr); |
| | | |
| | | double th = (double) m_pRecipe->m_SideParam[(int) emDim].m_NotchPrm[nNotchIdx].m_nReferece_Line_Threshold; |
| | | int nNotchCenterOffset = m_pRecipe->m_SideParam[(int) emDim].m_NotchPrm[nNotchIdx].m_nNotchCenter_Offset_pxl; |
| | | double th = (double)m_pRecipe->m_SideParam[(int)emDim].m_NotchPrm[nNotchIdx].m_nReferece_Line_Threshold; |
| | | int nNotchCenterOffset = m_pRecipe->m_SideParam[(int)emDim].m_NotchPrm[nNotchIdx].m_nNotchCenter_Offset_pxl; |
| | | |
| | | cvThreshold(scr, img_Bin_MeasureLine, th, 255, CV_THRESH_BINARY); |
| | | |
| | |
| | | ptSeed.y = img_Bin_MeasureLine->height / 2; |
| | | |
| | | img_Find_MeasureLine = cvCloneImage(img_Bin_MeasureLine); |
| | | // cvFloodFill(img_Find_MeasureLine, ptSeed, CV_RGB(255,255,255)); // 拱 锭巩俊 急捞 谗绢瘤绰 版快啊 乐绢辑 救茄促. |
| | | // cvFloodFill(img_Find_MeasureLine, ptSeed, CV_RGB(255,255,255)); // 물 때문에 선이 끊어지는 경우가 있어서 안한다. |
| | | // cvThreshold(img_Find_MeasureLine, img_Find_MeasureLine, 100, 255, CV_THRESH_BINARY); |
| | | |
| | | // 2. Find Curve Line |
| | | double dStepAngle = 1.0; |
| | | int nFindStep = (int) (360.0 / dStepAngle); |
| | | int nSkipStep = 30; // 贸澜 30档, 场 30档绰 胶诺茄促. |
| | | int nFindStep = (int)(360.0 / dStepAngle); |
| | | int nSkipStep = 30; // 처음 30도, 끝 30도는 스킵한다. |
| | | |
| | | IplImage* img_Find_MeasureLine_Point = cvCloneImage(scr); |
| | | |
| | | std::vector<CPoint> vecPointList; |
| | | |
| | | for(int i=nSkipStep; i < nFindStep-nSkipStep; i++) |
| | | for (int i = nSkipStep; i < nFindStep - nSkipStep; i++) |
| | | { |
| | | double dFindAngle = ((double) i) * dStepAngle; |
| | | double dFindAngle = ((double)i) * dStepAngle; |
| | | |
| | | double dSearchRadius = 1800.0 + abs(nNotchCenterOffset); |
| | | |
| | | for(double dRadius = 0.0; dRadius < dSearchRadius; dRadius += 0.5) |
| | | for (double dRadius = 0.0; dRadius < dSearchRadius; dRadius += 0.5) |
| | | { |
| | | int nX = (int) (ptSeed.x - (cos(ToRadian(dFindAngle)) * dRadius)); |
| | | int nY = (int) (ptSeed.y - (sin(ToRadian(dFindAngle)) * dRadius)); |
| | | int nX = (int)(ptSeed.x - (cos(ToRadian(dFindAngle)) * dRadius)); |
| | | int nY = (int)(ptSeed.y - (sin(ToRadian(dFindAngle)) * dRadius)); |
| | | |
| | | if(nX < 0 ||img_Find_MeasureLine->width <= nX) |
| | | if (nX < 0 || img_Find_MeasureLine->width <= nX) |
| | | continue; |
| | | |
| | | if(nY < 0 ||img_Find_MeasureLine->height <= nY) |
| | | if (nY < 0 || img_Find_MeasureLine->height <= nY) |
| | | continue; |
| | | |
| | | if(img_Find_MeasureLine->imageData[nY * img_Find_MeasureLine->widthStep + nX] != 0) |
| | | if (img_Find_MeasureLine->imageData[nY * img_Find_MeasureLine->widthStep + nX] != 0) |
| | | { |
| | | img_Find_MeasureLine_Point->imageData[nY * img_Find_MeasureLine_Point->widthStep + nX] = 255; |
| | | |
| | |
| | | } |
| | | |
| | | // 3. Meausre |
| | | int nCount = vecPointList.size()-2; |
| | | int nCount = vecPointList.size() - 2; |
| | | |
| | | if(nCount < MAX_SIDE_NOTCH_MEASURE_COUNT) // 螟沥 器牢飘 俊矾 |
| | | if (nCount < MAX_SIDE_NOTCH_MEASURE_COUNT) // 측정 포인트 에러 |
| | | { |
| | | cvReleaseImage(&img_Bin_MeasureLine); |
| | | cvReleaseImage(&img_Find_MeasureLine); |
| | |
| | | return; |
| | | } |
| | | |
| | | double dPointStep = (double) nCount / (MAX_SIDE_NOTCH_MEASURE_COUNT-1); // 16 Point 螟沥.. |
| | | double dPointStep = (double)nCount / (MAX_SIDE_NOTCH_MEASURE_COUNT - 1); // 16 Point 측정.. |
| | | |
| | | for(int nMeasureIdx=0; nMeasureIdx < MAX_SIDE_NOTCH_MEASURE_COUNT; nMeasureIdx++) |
| | | for (int nMeasureIdx = 0; nMeasureIdx < MAX_SIDE_NOTCH_MEASURE_COUNT; nMeasureIdx++) |
| | | { |
| | | int nPointIdx = nMeasureIdx * dPointStep; |
| | | int nPointIdx = nMeasureIdx * (int)dPointStep; |
| | | |
| | | if(nPointIdx == 0) nPointIdx = 1; |
| | | else if(vecPointList.size() <= nPointIdx) nPointIdx = vecPointList.size() - 1; |
| | | if (nPointIdx == 0) nPointIdx = 1; |
| | | else if (vecPointList.size() <= nPointIdx) nPointIdx = vecPointList.size() - 1; |
| | | |
| | | CPoint pt_Start = vecPointList[nPointIdx-1]; |
| | | CPoint pt_End = vecPointList[nPointIdx+1]; |
| | | CPoint pt_Measure = vecPointList[nPointIdx]; |
| | | CPoint pt_Start = vecPointList[nPointIdx - 1]; |
| | | CPoint pt_End = vecPointList[nPointIdx + 1]; |
| | | CPoint pt_Measure = vecPointList[nPointIdx]; |
| | | |
| | | m_pGlassData->GetSideData(emDim)->m_ptNotch_Reference[nNotchIdx][nMeasureIdx].x = pt_Measure.x; // + rtROI.left; |
| | | m_pGlassData->GetSideData(emDim)->m_ptNotch_Reference[nNotchIdx][nMeasureIdx].y = pt_Measure.y + rtROI.top; |
| | |
| | | |
| | | double dAngle_Radian = ToRadian(-90.0); |
| | | |
| | | if(dDiff_X != 0.0) |
| | | dAngle_Radian = atan(dDiff_y/dDiff_X); |
| | | if (dDiff_X != 0.0) |
| | | dAngle_Radian = atan(dDiff_y / dDiff_X); |
| | | |
| | | dAngle_Radian = ToRadian( 90.0 - abs(ToDegree(dAngle_Radian)) ); |
| | | dAngle_Radian = ToRadian(90.0 - abs(ToDegree(dAngle_Radian))); |
| | | |
| | | if(pt_End.x - pt_Start.x < 0.0) |
| | | if (pt_End.x - pt_Start.x < 0.0) |
| | | dAngle_Radian = dAngle_Radian * -1.0; |
| | | |
| | | double dSearchRadius = 100.0; |
| | |
| | | |
| | | BOOL bEdgeCheck = FALSE; |
| | | |
| | | for(double dRadius = 0.0; dRadius < dSearchRadius; dRadius += 0.2) |
| | | for (double dRadius = 0.0; dRadius < dSearchRadius; dRadius += 0.2) |
| | | { |
| | | double dMeasureRadius = dSearchRadius - dRadius; |
| | | |
| | | int nX = pt_Measure.x - (cos(dAngle_Radian) * dMeasureRadius); |
| | | int nY = pt_Measure.y + (sin(dAngle_Radian) * dMeasureRadius); |
| | | int nX = (int)(pt_Measure.x - (cos(dAngle_Radian) * dMeasureRadius)); |
| | | int nY = (int)(pt_Measure.y + (sin(dAngle_Radian) * dMeasureRadius)); |
| | | |
| | | img_Result->imageData[pt_Measure.y * img_Result->widthStep + pt_Measure.x] = 0; |
| | | |
| | | if(nX < 0 ||img_Edge->width <= nX) |
| | | if (nX < 0 || img_Edge->width <= nX) |
| | | continue; |
| | | |
| | | if(nY < 0 ||img_Edge->height <= nY) |
| | | if (nY < 0 || img_Edge->height <= nY) |
| | | continue; |
| | | |
| | | CPoint ptCheck = CPoint(nX, nY); |
| | |
| | | BOOL bEdgeFind = FALSE; |
| | | BOOL bBinEdgeFind = FALSE; |
| | | |
| | | for(int nCheckX = 0; nCheckX < 3; nCheckX++) |
| | | for (int nCheckX = 0; nCheckX < 3; nCheckX++) |
| | | { |
| | | for(int nCheckY = 0; nCheckY < 3; nCheckY++) |
| | | for (int nCheckY = 0; nCheckY < 3; nCheckY++) |
| | | { |
| | | int nFindX = nX - 1 + nCheckX; |
| | | int nFindY = nY - 1 + nCheckY; |
| | | |
| | | if(nFindX < 0 ||img_Edge->width <= nFindX) |
| | | if (nFindX < 0 || img_Edge->width <= nFindX) |
| | | continue; |
| | | |
| | | if(nFindY < 0 ||img_Edge->height <= nFindY) |
| | | if (nFindY < 0 || img_Edge->height <= nFindY) |
| | | continue; |
| | | |
| | | if(img_Edge->imageData[nFindY * img_Edge->widthStep + nFindX] != 0) |
| | | if (img_Edge->imageData[nFindY * img_Edge->widthStep + nFindX] != 0) |
| | | { |
| | | bEdgeFind = TRUE; |
| | | //break; |
| | | } |
| | | if(img_Bin->imageData[nFindY * img_Bin->widthStep + nFindX] != 0) |
| | | if (img_Bin->imageData[nFindY * img_Bin->widthStep + nFindX] != 0) |
| | | { |
| | | bBinEdgeFind = TRUE; |
| | | //break; |
| | | } |
| | | |
| | | if(bEdgeFind == TRUE && bBinEdgeFind == TRUE) |
| | | if (bEdgeFind == TRUE && bBinEdgeFind == TRUE) |
| | | break; |
| | | } |
| | | |
| | | if(bEdgeFind == TRUE && bBinEdgeFind == TRUE) |
| | | break; |
| | | if (bEdgeFind == TRUE && bBinEdgeFind == TRUE) |
| | | break; |
| | | } |
| | | |
| | | if(bEdgeCheck == FALSE && (bEdgeFind == TRUE || bBinEdgeFind == TRUE)) |
| | | if (bEdgeCheck == FALSE && (bEdgeFind == TRUE || bBinEdgeFind == TRUE)) |
| | | { |
| | | if(bFindEdge == FALSE && bEdgeFind == TRUE) |
| | | if (bFindEdge == FALSE && bEdgeFind == TRUE) |
| | | { |
| | | img_Result->imageData[nY * img_Result->widthStep + nX] = 255; |
| | | bFindEdge = TRUE; |
| | |
| | | } |
| | | |
| | | //if(ptCheck != ptFindEdge && bFindEdge == TRUE && bFindChamfer == FALSE) |
| | | if(ptCheck != ptFindEdge && bBinEdgeFind == TRUE && bFindChamfer == FALSE) |
| | | if (ptCheck != ptFindEdge && bBinEdgeFind == TRUE && bFindChamfer == FALSE) |
| | | { |
| | | img_Result->imageData[nY * img_Result->widthStep + nX] = 200; |
| | | bFindChamfer = TRUE; |
| | |
| | | m_pGlassData->GetSideData(emDim)->m_ptNotch_Chamfer_Edge[nNotchIdx][nMeasureIdx].y = ptFindChamfer.y + rtROI.top; |
| | | } |
| | | } |
| | | else if(bEdgeCheck == TRUE && bEdgeFind == FALSE) |
| | | else if (bEdgeCheck == TRUE && bEdgeFind == FALSE) |
| | | { |
| | | bEdgeCheck = FALSE; |
| | | } |
| | | |
| | | if(bFindEdge == TRUE && bFindChamfer == TRUE) |
| | | if (bFindEdge == TRUE && bFindChamfer == TRUE) |
| | | break; |
| | | } |
| | | } |
| | |
| | | return; |
| | | } |
| | | |
| | | bool CInspectCamera::Notch_Process_Calculate(DimensionDir emDim, stFrameIndex stFrame, int nNotchIdx, IplImage* scr,IplImage* img_Edge,IplImage* img_Bin, CRect rtROI) |
| | | bool CInspectCamera::Notch_Process_Calculate(DimensionDir emDim, stFrameIndex stFrame, int nNotchIdx, IplImage* scr, IplImage* img_Edge, IplImage* img_Bin, CRect rtROI) |
| | | { |
| | | if(m_pRecipe == NULL || m_pGlassData == NULL) |
| | | if (m_pRecipe == NULL || m_pGlassData == NULL) |
| | | return FALSE; |
| | | |
| | | for(int nMeasureIdx=0; nMeasureIdx < MAX_SIDE_NOTCH_MEASURE_COUNT; nMeasureIdx++) |
| | | int NotchFlag = 0; |
| | | for (int nMeasureIdx = 0; nMeasureIdx < MAX_SIDE_NOTCH_MEASURE_COUNT; nMeasureIdx++) |
| | | { |
| | | CPoint ptRef_pxl = m_pGlassData->GetSideData(emDim)->m_ptNotch_Reference[nNotchIdx][nMeasureIdx]; |
| | | CPoint ptDim_pxl = m_pGlassData->GetSideData(emDim)->m_ptNotch_Dimension_Edge[nNotchIdx][nMeasureIdx]; |
| | | |
| | | if (ptRef_pxl.x < 0 || ptRef_pxl.y < 0) { |
| | | |
| | | /* 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; |
| | | } |
| | | }*/ |
| | | |
| | | // Dimension |
| | | double dX_dim_um = (double)(ptRef_pxl.x - ptDim_pxl.x) * m_dPixelSizeX; |
| | |
| | | m_pGlassData->GetSideData(emDim)->m_dNotch_Dimension_Edge_Result_um[nNotchIdx][nMeasureIdx] = dDimension; |
| | | |
| | | CPoint ptChamfer_pxl = m_pGlassData->GetSideData(emDim)->m_ptNotch_Chamfer_Edge[nNotchIdx][nMeasureIdx]; |
| | | if (ptChamfer_pxl.x < 0 || ptChamfer_pxl.y < 0) { |
| | | /* 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; |
| | | } |
| | | }*/ |
| | | |
| | | double dX_Chamfer = (double)(ptChamfer_pxl.x - ptDim_pxl.x) * m_dPixelSizeX; |
| | | double dY_Chamfer = (double)(ptChamfer_pxl.y - ptDim_pxl.y) * m_dPixelSizeY; |
| | | double dChamfer = sqrtf((dX_Chamfer * dX_Chamfer) + (dY_Chamfer * dY_Chamfer)); |
| | | m_pGlassData->GetSideData(emDim)->m_dNotch_Chamfer_Edge_Result_um[nNotchIdx][nMeasureIdx] = dChamfer; |
| | | |
| | | if (dDimension > 2000.0 && dChamfer > 2000.0) { |
| | | if (dDimension > 5000.0 && dChamfer > 5000.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; |
| | | NotchFlag=1; |
| | | } |
| | | } |
| | | |
| | | if (NotchFlag == TRUE) |
| | | { |
| | | return FALSE; |
| | | }else |
| | | return TRUE; |
| | | } |
| | | |
| | | void CInspectCamera::Notch_Process_Judge(DimensionDir emDim, stFrameIndex stFrame, int nNotchIdx, IplImage* scr,IplImage* img_Edge,IplImage* img_Bin, CRect rtROI) |
| | | void CInspectCamera::Notch_Process_Judge(DimensionDir emDim, stFrameIndex stFrame, int nNotchIdx, IplImage* scr, IplImage* img_Edge, IplImage* img_Bin, CRect rtROI) |
| | | { |
| | | if (m_pRecipe == NULL || m_pGlassData == NULL) { |
| | | g_pLog->DisplayMessage(_T("[ERROR] Recipe or Glass Data is NULL in Notch_Process_Judge")); |
| | |
| | | return; |
| | | } |
| | | |
| | | for(int nMeasureIdx=0; nMeasureIdx < MAX_SIDE_NOTCH_MEASURE_COUNT; nMeasureIdx++) |
| | | for (int nMeasureIdx = 0; nMeasureIdx < MAX_SIDE_NOTCH_MEASURE_COUNT; nMeasureIdx++) |
| | | { |
| | | // Dimension |
| | | if(m_pRecipe->m_SideParam[(int) emDim].m_NotchPrm[nNotchIdx].m_bNotch_Dimension_Use[nMeasureIdx] == TRUE) |
| | | if (m_pRecipe->m_SideParam[(int)emDim].m_NotchPrm[nNotchIdx].m_bNotch_Dimension_Use[nMeasureIdx] == TRUE) |
| | | { |
| | | double dDimension_um = pSideData->m_dNotch_Dimension_Edge_Result_um[nNotchIdx][nMeasureIdx]; |
| | | double dDimension_std_um = m_pRecipe->m_SideParam[(int) emDim].m_NotchPrm[nNotchIdx].m_dNotch_Dimension_STD_mm[nMeasureIdx] * 1000.0; |
| | | double dDimension_min_um = m_pRecipe->m_SideParam[(int) emDim].m_NotchPrm[nNotchIdx].m_dNotch_Dimension_Diff_MIN_mm[nMeasureIdx] * 1000.0; |
| | | double dDimension_max_um = m_pRecipe->m_SideParam[(int) emDim].m_NotchPrm[nNotchIdx].m_dNotch_Dimension_Diff_MAX_mm[nMeasureIdx] * 1000.0; |
| | | double dDimension_std_um = m_pRecipe->m_SideParam[(int)emDim].m_NotchPrm[nNotchIdx].m_dNotch_Dimension_STD_mm[nMeasureIdx] * 1000.0; |
| | | double dDimension_min_um = m_pRecipe->m_SideParam[(int)emDim].m_NotchPrm[nNotchIdx].m_dNotch_Dimension_Diff_MIN_mm[nMeasureIdx] * 1000.0; |
| | | double dDimension_max_um = m_pRecipe->m_SideParam[(int)emDim].m_NotchPrm[nNotchIdx].m_dNotch_Dimension_Diff_MAX_mm[nMeasureIdx] * 1000.0; |
| | | double dDimension_Diff_um = dDimension_std_um - dDimension_um; |
| | | |
| | | pSideData->m_nNotch_Dimension_Edge_Judge[nNotchIdx][nMeasureIdx] = 1; |
| | |
| | | pSideData->m_dNotch_Dimension_Edge_Judge_Min_um[nNotchIdx][nMeasureIdx] = dDimension_min_um; |
| | | pSideData->m_dNotch_Dimension_Edge_Judge_Max_um[nNotchIdx][nMeasureIdx] = dDimension_max_um; |
| | | |
| | | if(dDimension_um > dDimension_std_um + dDimension_max_um) |
| | | if (dDimension_um > dDimension_std_um + dDimension_max_um) |
| | | pSideData->m_nNotch_Dimension_Edge_Judge[nNotchIdx][nMeasureIdx] = 2; |
| | | else if(dDimension_um < dDimension_std_um - dDimension_min_um) |
| | | else if (dDimension_um < dDimension_std_um - dDimension_min_um) |
| | | pSideData->m_nNotch_Dimension_Edge_Judge[nNotchIdx][nMeasureIdx] = 3; |
| | | |
| | | if(pSideData->m_nNotch_Dimension_Edge_Judge[nNotchIdx][nMeasureIdx] != 1) |
| | | if (pSideData->m_nNotch_Dimension_Edge_Judge[nNotchIdx][nMeasureIdx] != 1) |
| | | { |
| | | // Make 搬窃.. |
| | | // Make 결함.. |
| | | CRect rtDefectArea = CRect(pSideData->m_ptNotch_Dimension_Edge[nNotchIdx][nMeasureIdx].x, |
| | | pSideData->m_ptNotch_Dimension_Edge[nNotchIdx][nMeasureIdx].y, |
| | | pSideData->m_ptNotch_Dimension_Edge[nNotchIdx][nMeasureIdx].x, |
| | | pSideData->m_ptNotch_Dimension_Edge[nNotchIdx][nMeasureIdx].y); |
| | | pSideData->m_ptNotch_Dimension_Edge[nNotchIdx][nMeasureIdx].y, |
| | | pSideData->m_ptNotch_Dimension_Edge[nNotchIdx][nMeasureIdx].x, |
| | | pSideData->m_ptNotch_Dimension_Edge[nNotchIdx][nMeasureIdx].y); |
| | | |
| | | rtDefectArea.InflateRect(10, 10); |
| | | |
| | | CDefect_Info defectInfo; |
| | | defectInfo.m_iFrameIdx = stFrame.nFrameIdx; |
| | | defectInfo.m_nCamID = m_iCamera; |
| | | defectInfo.m_nScanIdx = stFrame.nScanIdx; |
| | | defectInfo.m_nGlassStartLine = pSideData->m_nGlassStartLine; |
| | | defectInfo.m_nSideIdx = (int) emDim; |
| | | defectInfo.m_ptDefectPos_pxl = rtDefectArea.CenterPoint(); |
| | | defectInfo.m_rtDefectPos_pxl = rtDefectArea; |
| | | defectInfo.m_DefectLoc = DefectLoc_Notch_Dimension; |
| | | defectInfo.m_iFrameIdx = stFrame.nFrameIdx; |
| | | defectInfo.m_nCamID = m_iCamera; |
| | | defectInfo.m_nScanIdx = stFrame.nScanIdx; |
| | | defectInfo.m_nGlassStartLine = pSideData->m_nGlassStartLine; |
| | | defectInfo.m_nSideIdx = (int)emDim; |
| | | defectInfo.m_ptDefectPos_pxl = rtDefectArea.CenterPoint(); |
| | | defectInfo.m_rtDefectPos_pxl = rtDefectArea; |
| | | defectInfo.m_DefectLoc = DefectLoc_Notch_Dimension; |
| | | |
| | | m_pDefectControl->ExtractDefect_Measure(emDim, m_iCamera, stFrame.nScanIdx, defectInfo, dDimension_um, dDimension_Diff_um); |
| | | } |
| | | } |
| | | |
| | | // Chamfer |
| | | if(m_pRecipe->m_SideParam[(int) emDim].m_NotchPrm[nNotchIdx].m_bNotch_Chamfer_Use[nMeasureIdx] == TRUE) |
| | | if (m_pRecipe->m_SideParam[(int)emDim].m_NotchPrm[nNotchIdx].m_bNotch_Chamfer_Use[nMeasureIdx] == TRUE) |
| | | { |
| | | double dChamfer_um = pSideData->m_dNotch_Chamfer_Edge_Result_um[nNotchIdx][nMeasureIdx]; |
| | | double dChamfer_std_um = m_pRecipe->m_SideParam[(int) emDim].m_NotchPrm[nNotchIdx].m_dNotch_Chamfer_STD_mm[nMeasureIdx] * 1000.0; |
| | | double dChamfer_min_um = m_pRecipe->m_SideParam[(int) emDim].m_NotchPrm[nNotchIdx].m_dNotch_Chamfer_Diff_MIN_mm[nMeasureIdx] * 1000.0; |
| | | double dChamfer_max_um = m_pRecipe->m_SideParam[(int) emDim].m_NotchPrm[nNotchIdx].m_dNotch_Chamfer_Diff_MAX_mm[nMeasureIdx] * 1000.0; |
| | | double dChamfer_std_um = m_pRecipe->m_SideParam[(int)emDim].m_NotchPrm[nNotchIdx].m_dNotch_Chamfer_STD_mm[nMeasureIdx] * 1000.0; |
| | | double dChamfer_min_um = m_pRecipe->m_SideParam[(int)emDim].m_NotchPrm[nNotchIdx].m_dNotch_Chamfer_Diff_MIN_mm[nMeasureIdx] * 1000.0; |
| | | double dChamfer_max_um = m_pRecipe->m_SideParam[(int)emDim].m_NotchPrm[nNotchIdx].m_dNotch_Chamfer_Diff_MAX_mm[nMeasureIdx] * 1000.0; |
| | | double dChamfer_Diff_um = dChamfer_std_um - dChamfer_um; |
| | | |
| | | pSideData->m_nNotch_Chamfer_Edge_Judge[nNotchIdx][nMeasureIdx] = 1; |
| | | //选取测量研磨尺寸最大值 |
| | | if (m_nChamferOffset_um < dChamfer_um) |
| | | { |
| | | |
| | | #if MINI_LED |
| | | //朞혤꿎좆桔칠넹당離댕令 |
| | | if (m_nChamferOffset_um < dChamfer_um) { |
| | | m_nChamferOffset_um = dChamfer_um; |
| | | } |
| | | #endif |
| | | |
| | | pSideData->m_dNotch_Chamfer_Edge_Result_Diff_um[nNotchIdx][nMeasureIdx] = dChamfer_std_um - dChamfer_um; |
| | | pSideData->m_dNotch_Chamfer_Edge_Judge_Std_um[nNotchIdx][nMeasureIdx] = dChamfer_std_um; |
| | | pSideData->m_dNotch_Chamfer_Edge_Judge_Min_um[nNotchIdx][nMeasureIdx] = dChamfer_min_um; |
| | | pSideData->m_dNotch_Chamfer_Edge_Judge_Max_um[nNotchIdx][nMeasureIdx] = dChamfer_max_um; |
| | | |
| | | if(dChamfer_um > dChamfer_std_um + dChamfer_max_um) |
| | | if (dChamfer_um > dChamfer_std_um + dChamfer_max_um) |
| | | pSideData->m_nNotch_Chamfer_Edge_Judge[nNotchIdx][nMeasureIdx] = 2; |
| | | else if(dChamfer_um < dChamfer_std_um - dChamfer_min_um) |
| | | else if (dChamfer_um < dChamfer_std_um - dChamfer_min_um) |
| | | pSideData->m_nNotch_Chamfer_Edge_Judge[nNotchIdx][nMeasureIdx] = 3; |
| | | |
| | | if(pSideData->m_nNotch_Chamfer_Edge_Judge[nNotchIdx][nMeasureIdx] != 1) |
| | | if (pSideData->m_nNotch_Chamfer_Edge_Judge[nNotchIdx][nMeasureIdx] != 1) |
| | | { |
| | | // Make 搬窃.. |
| | | // Make 결함.. |
| | | CRect rtDefectArea = CRect(pSideData->m_ptNotch_Chamfer_Edge[nNotchIdx][nMeasureIdx].x, |
| | | pSideData->m_ptNotch_Chamfer_Edge[nNotchIdx][nMeasureIdx].y, |
| | | pSideData->m_ptNotch_Chamfer_Edge[nNotchIdx][nMeasureIdx].x, |
| | | pSideData->m_ptNotch_Chamfer_Edge[nNotchIdx][nMeasureIdx].y); |
| | | pSideData->m_ptNotch_Chamfer_Edge[nNotchIdx][nMeasureIdx].y, |
| | | pSideData->m_ptNotch_Chamfer_Edge[nNotchIdx][nMeasureIdx].x, |
| | | pSideData->m_ptNotch_Chamfer_Edge[nNotchIdx][nMeasureIdx].y); |
| | | |
| | | rtDefectArea.InflateRect(10, 10); |
| | | |
| | | CDefect_Info defectInfo; |
| | | defectInfo.m_iFrameIdx = stFrame.nFrameIdx; |
| | | defectInfo.m_nCamID = m_iCamera; |
| | | defectInfo.m_nScanIdx = stFrame.nScanIdx; |
| | | defectInfo.m_nGlassStartLine = pSideData->m_nGlassStartLine; |
| | | defectInfo.m_nSideIdx = (int) emDim; |
| | | defectInfo.m_ptDefectPos_pxl = rtDefectArea.CenterPoint(); |
| | | defectInfo.m_rtDefectPos_pxl = rtDefectArea; |
| | | defectInfo.m_DefectLoc = DefectLoc_Notch_Chamfer; |
| | | defectInfo.m_iFrameIdx = stFrame.nFrameIdx; |
| | | defectInfo.m_nCamID = m_iCamera; |
| | | defectInfo.m_nScanIdx = stFrame.nScanIdx; |
| | | defectInfo.m_nGlassStartLine = pSideData->m_nGlassStartLine; |
| | | defectInfo.m_nSideIdx = (int)emDim; |
| | | defectInfo.m_ptDefectPos_pxl = rtDefectArea.CenterPoint(); |
| | | defectInfo.m_rtDefectPos_pxl = rtDefectArea; |
| | | defectInfo.m_DefectLoc = DefectLoc_Notch_Chamfer; |
| | | |
| | | m_pDefectControl->ExtractDefect_Measure(emDim, m_iCamera, stFrame.nScanIdx, defectInfo, dChamfer_um, dChamfer_Diff_um); |
| | | } |
| | | } |
| | | |
| | | // Make Comment |
| | | char strJudge[4][16] = {"None", "OK", "OV", "UN"}; |
| | | char strJudge[4][16] = { "None", "OK", "OV", "UN" }; |
| | | sprintf(pSideData->m_strNotchMeasure_Comment[nNotchIdx][nMeasureIdx], "NOTCH[%d]-POINT[%d]-DIM[%.1f/STD:%.1f][%s], CHAMFER[%.1f/STD:%.1f][%s]" |
| | | , nNotchIdx+1, nMeasureIdx+1 |
| | | , nNotchIdx + 1, nMeasureIdx + 1 |
| | | , pSideData->m_dNotch_Dimension_Edge_Result_um[nNotchIdx][nMeasureIdx] |
| | | , pSideData->m_dNotch_Dimension_Edge_Judge_Std_um[nNotchIdx][nMeasureIdx] |
| | | , strJudge[pSideData->m_nNotch_Dimension_Edge_Judge[nNotchIdx][nMeasureIdx]] |
| | | , pSideData->m_dNotch_Chamfer_Edge_Result_um[nNotchIdx][nMeasureIdx] |
| | | , pSideData->m_dNotch_Chamfer_Edge_Judge_Std_um[nNotchIdx][nMeasureIdx] |
| | | , strJudge[pSideData->m_nNotch_Chamfer_Edge_Judge[nNotchIdx][nMeasureIdx]]); |
| | | , strJudge[pSideData->m_nNotch_Dimension_Edge_Judge[nNotchIdx][nMeasureIdx]] |
| | | , pSideData->m_dNotch_Chamfer_Edge_Result_um[nNotchIdx][nMeasureIdx] |
| | | , pSideData->m_dNotch_Chamfer_Edge_Judge_Std_um[nNotchIdx][nMeasureIdx] |
| | | , strJudge[pSideData->m_nNotch_Chamfer_Edge_Judge[nNotchIdx][nMeasureIdx]]); |
| | | } |
| | | } |
| | | |
| | | void CInspectCamera::Notch_Process_Defect(DimensionDir emDim, stFrameIndex stFrame, int nNotchIdx, IplImage* scr,IplImage* img_Edge,IplImage* img_Bin, CRect rtROI) |
| | | void CInspectCamera::Notch_Process_Defect(DimensionDir emDim, stFrameIndex stFrame, int nNotchIdx, IplImage* scr, IplImage* img_Edge, IplImage* img_Bin, CRect rtROI) |
| | | { |
| | | if(m_pGlassData == NULL || m_pRecipe == NULL) |
| | | if (m_pGlassData == NULL || m_pRecipe == NULL) |
| | | return; |
| | | |
| | | if(scr == NULL) |
| | | if (scr == NULL) |
| | | return; |
| | | |
| | | CNOTCH_PARM* pNotchParam = &m_pRecipe->m_SideParam[(int) emDim].m_NotchPrm[nNotchIdx]; |
| | | CNOTCH_PARM* pNotchParam = &m_pRecipe->m_SideParam[(int)emDim].m_NotchPrm[nNotchIdx]; |
| | | |
| | | if(pNotchParam->m_bNotch_Inspect_Defect_Use == FALSE) |
| | | if (pNotchParam->m_bNotch_Inspect_Defect_Use == FALSE) |
| | | return; |
| | | |
| | | |
| | | CString strTemp; |
| | | |
| | | int nSide = (int) emDim; |
| | | |
| | | int nSide = (int)emDim; |
| | | int nThreshold = pNotchParam->m_nNotch_Inspect_Defect_Threshold; |
| | | int nOffset = pNotchParam->m_nNotch_Inspect_Defect_Offset; |
| | | |
| | | #if MINI_NOTCH //Defect检测开关, jiang |
| | | #if MINI_NOTCH //Defect쇱꿎역밑, jiang |
| | | int nEdgeThres = pNotchParam->m_nGrind_Threshold; |
| | | int nNgType = pNotchParam->m_nNotch_Inspect_Defect_Judge_And; |
| | | int xNgSize = pNotchParam->m_nNotch_Inspect_Defect_Judge_X_um; |
| | | int yNgSize = pNotchParam->m_nNotch_Inspect_Defect_Judge_Y_um; |
| | | |
| | | Log_GetDebug()->TraceInfo("Norch Info: %d, (%d, %d, %d, %d), ROI(%d, %d, %d, %d), %d", |
| | | |
| | | Log_GetDebug()->TraceInfo("Norch Info: %d, (%d, %d, %d, %d), ROI(%d, %d, %d, %d), %d", |
| | | nNotchIdx, nEdgeThres, nThreshold, nOffset, nNgType, |
| | | rtROI.left, rtROI.top, rtROI.right, rtROI.bottom, __LINE__); |
| | | |
| | | //输出计算信息 |
| | | //渴놔셕炬斤口 |
| | | std::vector<Point2D> vNorchPoints; |
| | | for (int nMeasureIdx = 0; nMeasureIdx < MAX_SIDE_NOTCH_MEASURE_COUNT; nMeasureIdx++){ |
| | | for (int nMeasureIdx = 0; nMeasureIdx < MAX_SIDE_NOTCH_MEASURE_COUNT; nMeasureIdx++) { |
| | | CPoint ptChamfer_pxl = m_pGlassData->GetSideData(emDim)->m_ptNotch_Chamfer_Edge[nNotchIdx][nMeasureIdx]; |
| | | Point2D point; |
| | | point.x = ptChamfer_pxl.x; |
| | | point.y = ptChamfer_pxl.y; |
| | | vNorchPoints.push_back(point); |
| | | vNorchPoints.push_back(point); |
| | | } |
| | | CRect defectResult[100]; |
| | | //nRet为缺陷数量,当前缺陷数 < 1时,表示为OK |
| | | //nRet槨홧屈鑒좆,뎠품홧屈鑒 < 1珂,깊刻槨OK |
| | | int nRet = BlVision_GetSoftVisionApp()->findNorchDefect(nSide, vNorchPoints, rtROI, nEdgeThres, nOffset, nThreshold, nNgType, xNgSize, yNgSize, defectResult); |
| | | printf("Norch Defect Number:%d\n", nRet); |
| | | |
| | |
| | | nOffset = m_nChamferOffset_um / m_pGlassData->GetSideData(emDim)->m_dPixelSizeX; |
| | | nOffset += pNotchParam->m_nNotch_Inspect_Defect_Offset; |
| | | m_nChamferOffset_um = 0; |
| | | #else |
| | | nOffset = pNotchParam->m_nNotch_Inspect_Defect_Offset; |
| | | #endif // MINI_LED |
| | | |
| | | // 렝岺법댕돔鈴봬珂샀코닸狂痙 |
| | | if (nOffset > 50) { |
| | | g_pLog->DisplayMessage(_T("[WARN] Notch defect offset capped to 50 pixels, original: %d"), nOffset); |
| | | nOffset = 50; |
| | | } |
| | | |
| | | CRect rcIns = rtROI; |
| | | rcIns.OffsetRect(-rcIns.left,-rcIns.top); |
| | | rcIns.OffsetRect(-rcIns.left, -rcIns.top); |
| | | IplImage* pProcImage = cvCreateImage(cvSize(rcIns.Width(), rcIns.Height()), 8, 1); |
| | | IplImage* pProcBinImage = cvCreateImage(cvSize(rcIns.Width(), rcIns.Height()), 8, 1); |
| | | IplImage* pProcessCanny = cvCreateImage(cvSize(rcIns.Width(), rcIns.Height()), 8, 1); |
| | |
| | | IplImage* pMaskImage = cvCreateImage(cvSize(rcIns.Width(), rcIns.Height()), 8, 1); |
| | | IplImage* pDilatedMaskImage = cvCreateImage(cvSize(rcIns.Width(), rcIns.Height()), 8, 1); |
| | | |
| | | for(int i=0; i<rcIns.Height(); i++) |
| | | for (int i = 0; i < rcIns.Height(); i++) |
| | | { |
| | | memcpy(pProcImage->imageData+(i*pProcImage->widthStep), scr->imageData+(rtROI.left + (i*scr->widthStep)), rcIns.Width()); |
| | | memcpy(pProcessCanny->imageData+(i*pProcessCanny->widthStep), img_Edge->imageData+(rtROI.left + (i*img_Edge->widthStep)), rcIns.Width()); |
| | | memcpy(pProcessBin->imageData+(i*pProcessBin->widthStep), img_Bin->imageData+(rtROI.left + (i*img_Bin->widthStep)), rcIns.Width()); |
| | | memcpy(pProcImage->imageData + (i * pProcImage->widthStep), scr->imageData + (rtROI.left + (i * scr->widthStep)), rcIns.Width()); |
| | | memcpy(pProcessCanny->imageData + (i * pProcessCanny->widthStep), img_Edge->imageData + (rtROI.left + (i * img_Edge->widthStep)), rcIns.Width()); |
| | | memcpy(pProcessBin->imageData + (i * pProcessBin->widthStep), img_Bin->imageData + (rtROI.left + (i * img_Bin->widthStep)), rcIns.Width()); |
| | | } |
| | | |
| | | strTemp.Format(_T("Notch\\Notch_%d_Defect_Edge"), nNotchIdx); |
| | |
| | | |
| | | strTemp.Format(_T("Notch\\Notch_%d_Defect_EdgeOrBin"), nNotchIdx); |
| | | SaveDebugImage(emDim, stFrame, pMaskImage, strTemp); |
| | | |
| | | |
| | | BOOL bFind; |
| | | int nFindX; |
| | | for(int y=0;y<pMaskImage->height;y++) |
| | | for (int y = 0; y < pMaskImage->height; y++) |
| | | { |
| | | bFind = FALSE; |
| | | nFindX = 0; |
| | | for(int x=0;x<pMaskImage->width;x++) |
| | | for (int x = 0; x < pMaskImage->width; x++) |
| | | { |
| | | if(pMaskImage->imageData[y*pMaskImage->widthStep + x] != 0) |
| | | if (pMaskImage->imageData[y * pMaskImage->widthStep + x] != 0) |
| | | { |
| | | bFind = TRUE; |
| | | nFindX = x; |
| | | break; |
| | | } |
| | | } |
| | | } |
| | | |
| | | if(bFind == TRUE) |
| | | if (bFind == TRUE) |
| | | { |
| | | memset(&pMaskImage->imageData[y*pMaskImage->widthStep], 255, nFindX); |
| | | memset(&pMaskImage->imageData[y*pMaskImage->widthStep+nFindX], 0, pMaskImage->width - nFindX); |
| | | memset(&pMaskImage->imageData[y * pMaskImage->widthStep], 255, nFindX); |
| | | memset(&pMaskImage->imageData[y * pMaskImage->widthStep + nFindX], 0, pMaskImage->width - nFindX); |
| | | } |
| | | } |
| | | |
| | | strTemp.Format(_T("Notch\\Notch_%d_Defect_MaskPreImage"), nNotchIdx); |
| | | SaveDebugImage(emDim, stFrame, pMaskImage, strTemp); |
| | | |
| | | if(0 < nOffset) |
| | | if (0 < nOffset) { |
| | | cvDilate(pMaskImage, pMaskImage, 0, nOffset); |
| | | } |
| | | |
| | | strTemp.Format(_T("Notch\\Notch_%d_Defect_MaskDilateImage"), nNotchIdx); |
| | | SaveDebugImage(emDim, stFrame, pMaskImage, strTemp); |
| | | |
| | | for(int i=0; i<pMaskImage->height; i++) |
| | | for(int j=0; j<pMaskImage->width; j++) |
| | | if(pMaskImage->imageData[i*pMaskImage->widthStep + j] != 0) |
| | | pProcImage->imageData[i*pProcImage->widthStep+j] = (char) 255; |
| | | for (int i = 0; i < pMaskImage->height; i++) |
| | | for (int j = 0; j < pMaskImage->width; j++) |
| | | if (pMaskImage->imageData[i * pMaskImage->widthStep + j] != 0) |
| | | pProcImage->imageData[i * pProcImage->widthStep + j] = (char)255; |
| | | |
| | | strTemp.Format(_T("Notch\\Notch_%d_Defect_ProcImage"), nNotchIdx); |
| | | SaveDebugImage(emDim, stFrame, pProcImage, strTemp); |
| | |
| | | strTemp.Format(_T("Notch\\Notch_%d_Defect_ProcBinImage"), nNotchIdx); |
| | | SaveDebugImage(emDim, stFrame, pProcBinImage, strTemp); |
| | | |
| | | #if MINI_LED == 0 |
| | | cvDilate(pMaskImage, pDilatedMaskImage, 0, pNotchParam->m_nNotch_Inspect_Defect_dilate); |
| | | strTemp.Format(_T("Notch\\Notch_%d_Defect_pMaskImage2"), nNotchIdx); |
| | | #if MINI_LED == 0 |
| | | // 掘齡툇郞늴鑒,렝岺법댕돔鈴봬珂샀코닸狂痙 |
| | | int nDilateCount = pNotchParam->m_nNotch_Inspect_Defect_dilate; |
| | | nDilateCount = std::max(0, std::min(nDilateCount, 50)); |
| | | if (pNotchParam->m_nNotch_Inspect_Defect_dilate != nDilateCount) { |
| | | g_pLog->DisplayMessage(_T("[WARN] Dilate count capped: Original=%d, Applied=%d"), pNotchParam->m_nNotch_Inspect_Defect_dilate, nDilateCount); |
| | | } |
| | | |
| | | if (nDilateCount > 0) { |
| | | cvDilate(pMaskImage, pDilatedMaskImage, 0, nDilateCount); |
| | | } |
| | | else { |
| | | cvCopy(pMaskImage, pDilatedMaskImage); |
| | | } |
| | | |
| | | strTemp.Format(_T("Notch\\Notch_%d_Defect_Mask_Dilated"), nNotchIdx); |
| | | SaveDebugImage(emDim, stFrame, pDilatedMaskImage, strTemp); |
| | | |
| | | cvAnd(pDilatedMaskImage, pProcBinImage, pDilatedMaskImage); |
| | | strTemp.Format(_T("Notch\\Notch_%d_Defect_pMaskImage3"), nNotchIdx); |
| | | strTemp.Format(_T("Notch\\Notch_%d_Defect_Mask_And_Bin"), nNotchIdx); |
| | | SaveDebugImage(emDim, stFrame, pDilatedMaskImage, strTemp); |
| | | #endif |
| | | |
| | |
| | | int iScan = stFrame.nScanIdx; |
| | | int iFrame = stFrame.nFrameIdx; |
| | | CRect rtProcessArea = rtROI; |
| | | |
| | | int nMinSize_X = pNotchParam->m_nNotch_Inspect_Defect_Min_X_um / m_pGlassData->GetSideData(emDim)->m_dPixelSizeX; |
| | | int nMinSize_Y = pNotchParam->m_nNotch_Inspect_Defect_Min_Y_um / m_pGlassData->GetSideData(emDim)->m_dPixelSizeY; |
| | | |
| | | |
| | | int nMinSize_X = (pNotchParam->m_nNotch_Inspect_Defect_Min_X_um / (int)m_pGlassData->GetSideData(emDim)->m_dPixelSizeX); |
| | | int nMinSize_Y = (pNotchParam->m_nNotch_Inspect_Defect_Min_Y_um / (int)m_pGlassData->GetSideData(emDim)->m_dPixelSizeY); |
| | | int nMinSize = 0; |
| | | |
| | | int nDilation = 0; |
| | |
| | | |
| | | std::vector<CDefect_Info> vecDefectCandidateList; |
| | | #if MINI_LED == 0 |
| | | DefectProcess(emDim, iScan, iFrame, pProcImage, pDilatedMaskImage, rtProcessArea, nMinSize, nMinSize_X, nMinSize_Y, nDilation, bStartNearFilterUse, nStartNearFilterRange, defectLoc, &vecDefectCandidateList); |
| | | DefectProcess(emDim, iScan, iFrame, pProcImage, pDilatedMaskImage, rtProcessArea, nMinSize, nMinSize_X, nMinSize_Y, nDilation, bStartNearFilterUse, nStartNearFilterRange, defectLoc, &vecDefectCandidateList); |
| | | #else |
| | | DefectProcess(emDim, iScan, iFrame, pProcImage, pProcBinImage, rtProcessArea, nMinSize, nMinSize_X, nMinSize_Y, nDilation, bStartNearFilterUse, nStartNearFilterRange, defectLoc, &vecDefectCandidateList); |
| | | DefectProcess(emDim, iScan, iFrame, pProcImage, pProcBinImage, rtProcessArea, nMinSize, nMinSize_X, nMinSize_Y, nDilation, bStartNearFilterUse, nStartNearFilterRange, defectLoc, &vecDefectCandidateList); |
| | | #endif |
| | | |
| | | |
| | | m_pDefectControl->ExtractDefect_Notch(emDim, m_iCamera, stFrame.nScanIdx, nNotchIdx, &vecDefectCandidateList); |
| | | |
| | | cvReleaseImage(&pDilatedMaskImage); |
| | | cvReleaseImage(&pMaskImage); |
| | | cvReleaseImage(&pProcImage); |
| | | cvReleaseImage(&pProcBinImage); |
| | | cvReleaseImage(&pProcessCanny); |
| | | cvReleaseImage(&pProcessCanny); |
| | | cvReleaseImage(&pProcessBin); |
| | | #endif |
| | | } |
| | | |
| | | void CInspectCamera::Notch_Process_FindCircle(DimensionDir emDim, stFrameIndex stFrame, int nNotchIdx) |
| | | { |
| | | if(m_pGlassData == NULL) |
| | | if (m_pGlassData == NULL) |
| | | return; |
| | | |
| | | CSide_Data* pSideData = m_pGlassData->GetSideData(emDim); |
| | | CSide_Data* pSideData = m_pGlassData->GetSideData(emDim); |
| | | |
| | | if(pSideData == NULL) |
| | | if (pSideData == NULL) |
| | | return; |
| | | |
| | | if(pSideData->m_bFindGlassEndLine == FALSE) // Notch Processing篮 End Line 茫篮 Frame捞.. |
| | | if (pSideData->m_bFindGlassEndLine == FALSE) // Notch Processing은 End Line 찾은 Frame이.. |
| | | return; |
| | | |
| | | if(m_pRecipe == NULL) |
| | | if (m_pRecipe == NULL) |
| | | return; |
| | | |
| | | if(m_pDefectControl == NULL) |
| | | if (m_pDefectControl == NULL) |
| | | return; |
| | | |
| | | CNOTCH_PARM* pNotchParam = &m_pRecipe->m_SideParam[(int) emDim].m_NotchPrm[nNotchIdx]; |
| | | CNOTCH_PARM* pNotchParam = &m_pRecipe->m_SideParam[(int)emDim].m_NotchPrm[nNotchIdx]; |
| | | |
| | | if(pNotchParam == NULL) |
| | | if (pNotchParam == NULL) |
| | | return; |
| | | |
| | | int nNotchCircleCount = pNotchParam->m_nNotch_Circle_Count; |
| | | |
| | | pSideData->m_nNotchCircleCount[nNotchIdx] = nNotchCircleCount; |
| | | |
| | | for(int nCircleIdx = 0; nCircleIdx < nNotchCircleCount; nCircleIdx++) |
| | | for (int nCircleIdx = 0; nCircleIdx < nNotchCircleCount; nCircleIdx++) |
| | | { |
| | | BOOL bUse = pNotchParam->m_bNotch_Circle_Use[nCircleIdx]; |
| | | |
| | | if(bUse == FALSE) |
| | | if (bUse == FALSE) |
| | | continue; |
| | | |
| | | // 1. Make ROI |
| | |
| | | VectorDouble vectorR; |
| | | |
| | | // 2. Get Edge Line |
| | | int nThreshold = m_pRecipe->m_SideParam[(int) emDim].m_nChamferLineThreshold; |
| | | int nThreshold = m_pRecipe->m_SideParam[(int)emDim].m_nChamferLineThreshold; |
| | | |
| | | LPBYTE pFrameBuffer = m_pGrabber->GetFrameHeader(stFrame.nScanIdx, 0); |
| | | |
| | |
| | | SaveDebugImage(emDim, stFrame, pCannyEdgeImage, strTemp); |
| | | |
| | | // Find Edge |
| | | for(int i=0; i<rtROI.Height(); i+=4) |
| | | for (int i = 0; i < rtROI.Height(); i += 4) |
| | | { |
| | | for(int j=0; j<rtROI.Width(); j++) |
| | | for (int j = 0; j < rtROI.Width(); j++) |
| | | { |
| | | BYTE nGray = pCannyEdgeImage->imageData[i * pCannyEdgeImage->widthStep + j]; |
| | | |
| | | if(nGray != 0 ) |
| | | if (nGray != 0) |
| | | { |
| | | double dX_um = j * m_dPixelSizeX; // rtROI.left + j; |
| | | double dY_um = i * m_dPixelSizeY; // rtROI.top + i; |
| | |
| | | cvReleaseImage(&pCannyEdgeImage); |
| | | |
| | | // 3. Circle Fitting |
| | | if(CCHDataFitting::CircleFitting(vectorX, vectorY, vectorR) == 1) |
| | | if (CCHDataFitting::CircleFitting(vectorX, vectorY, vectorR) == 1) |
| | | { |
| | | double dCenterPos_X_um = vectorR[0]; |
| | | double dCenterPos_Y_um = vectorR[1]; |
| | |
| | | double dCenterPos_Y_pxl = rtROI.top + (dCenterPos_Y_um / m_dPixelSizeY); |
| | | |
| | | pSideData->m_nNotchCircle_Radius_Judge[nNotchIdx][nCircleIdx] = 1; |
| | | pSideData->m_ptNotchCircle_Center_pxl[nNotchIdx][nCircleIdx].x = dCenterPos_X_pxl; |
| | | pSideData->m_ptNotchCircle_Center_pxl[nNotchIdx][nCircleIdx].y = dCenterPos_Y_pxl; |
| | | pSideData->m_ptNotchCircle_Center_pxl[nNotchIdx][nCircleIdx].x = (LONG)dCenterPos_X_pxl; |
| | | pSideData->m_ptNotchCircle_Center_pxl[nNotchIdx][nCircleIdx].y = (LONG)dCenterPos_Y_pxl; |
| | | pSideData->m_ptNotchCircle_Radius_Result_X_pxl[nNotchIdx][nCircleIdx] = dRadiuse_um / m_dPixelSizeX; |
| | | pSideData->m_ptNotchCircle_Radius_Result_Y_pxl[nNotchIdx][nCircleIdx] = dRadiuse_um / m_dPixelSizeY; |
| | | pSideData->m_ptNotchCircle_Radius_Result_um[nNotchIdx][nCircleIdx] = dRadiuse_um; |
| | | |
| | | // Judge.. |
| | | |
| | | double dStd_um = m_pRecipe->m_SideParam[(int) emDim].m_NotchPrm[nNotchIdx].m_dNotch_Circle_Spec_Radius_um[nCircleIdx]; |
| | | double dMin_um = abs(m_pRecipe->m_SideParam[(int) emDim].m_NotchPrm[nNotchIdx].m_dNotch_Circle_Spec_Radius_Min_um[nCircleIdx]) * -1.0; |
| | | double dMax_um = abs(m_pRecipe->m_SideParam[(int) emDim].m_NotchPrm[nNotchIdx].m_dNotch_Circle_Spec_Radius_Max_um[nCircleIdx]); |
| | | double dStd_um = m_pRecipe->m_SideParam[(int)emDim].m_NotchPrm[nNotchIdx].m_dNotch_Circle_Spec_Radius_um[nCircleIdx]; |
| | | double dMin_um = abs(m_pRecipe->m_SideParam[(int)emDim].m_NotchPrm[nNotchIdx].m_dNotch_Circle_Spec_Radius_Min_um[nCircleIdx]) * -1.0; |
| | | double dMax_um = abs(m_pRecipe->m_SideParam[(int)emDim].m_NotchPrm[nNotchIdx].m_dNotch_Circle_Spec_Radius_Max_um[nCircleIdx]); |
| | | |
| | | double dResult_um = dStd_um - dRadiuse_um; |
| | | |
| | | pSideData->m_ptNotchCircle_Radius_Judge_Std_um[nNotchIdx][nCircleIdx] = dStd_um; |
| | | pSideData->m_ptNotchCircle_Radius_Judge_Min_um[nNotchIdx][nCircleIdx] = dMin_um; |
| | | pSideData->m_ptNotchCircle_Radius_Judge_Max_um[nNotchIdx][nCircleIdx] = dMax_um; |
| | | pSideData->m_ptNotchCircle_Radius_Judge_Std_um[nNotchIdx][nCircleIdx] = dStd_um; |
| | | pSideData->m_ptNotchCircle_Radius_Judge_Min_um[nNotchIdx][nCircleIdx] = dMin_um; |
| | | pSideData->m_ptNotchCircle_Radius_Judge_Max_um[nNotchIdx][nCircleIdx] = dMax_um; |
| | | pSideData->m_ptNotchCircle_Radius_Result_Diff_um[nNotchIdx][nCircleIdx] = dResult_um; |
| | | |
| | | if(dResult_um < dMin_um || dMax_um < dResult_um) |
| | | if (dResult_um < dMin_um || dMax_um < dResult_um) |
| | | { |
| | | pSideData->m_nNotchCircle_Radius_Judge[nNotchIdx][nCircleIdx] = 2; // NG |
| | | |
| | |
| | | measureDefect.m_nCamID = m_iCamera; |
| | | measureDefect.m_nScanIdx = stFrame.nScanIdx; |
| | | measureDefect.m_nGlassStartLine = pSideData->m_nGlassStartLine; |
| | | measureDefect.m_nSideIdx = (int) emDim; |
| | | measureDefect.m_nSideIdx = (int)emDim; |
| | | measureDefect.m_DefectLoc = DefectLoc_Notch_Circle_Radius; |
| | | measureDefect.m_ptDefectPos_pxl = rtROI.CenterPoint(); // CPoint(nEndPointPosX, nEndPointPosY); |
| | | measureDefect.m_rtDefectPos_pxl = CRect(rtROI.CenterPoint().x - 16, rtROI.CenterPoint().y - 16, rtROI.CenterPoint().x + 16, rtROI.CenterPoint().y + 16); |
| | | |
| | | m_pDefectControl->ExtractDefect_Measure(emDim, m_iCamera, stFrame.nScanIdx, measureDefect, dRadiuse_um, dResult_um); |
| | | |
| | | sprintf(pSideData->m_strNotchCircle_Radius_Comment[nNotchIdx][nCircleIdx], "Rad. [NG] %.1f um / %.1f um", dRadiuse_um, dResult_um); |
| | | sprintf(pSideData->m_strNotchCircle_Radius_Comment[nNotchIdx][nCircleIdx], "Rad. [NG] %.1f um / %.1f um", dRadiuse_um, dResult_um); |
| | | } |
| | | else |
| | | { |
| | |
| | | } |
| | | } |
| | | |
| | | BOOL CInspectCamera::Measure(int iThread,DimensionDir emDim, stFrameIndex stFrame) |
| | | BOOL CInspectCamera::Measure(int iThread, DimensionDir emDim, stFrameIndex stFrame) |
| | | { |
| | | |
| | | if(m_pGlassData == NULL) |
| | | if (m_pGlassData == NULL) |
| | | return FALSE; |
| | | |
| | | CSide_Data* pSideData = m_pGlassData->GetSideData(emDim); |
| | | CSide_Data* pSideData = m_pGlassData->GetSideData(emDim); |
| | | |
| | | if(pSideData == NULL) |
| | | if (pSideData == NULL) |
| | | return FALSE; |
| | | |
| | | int nEndFrame = pSideData->m_nGlassEndLine/m_nFrameHeight; |
| | | int nEndFrame = pSideData->m_nGlassEndLine / m_nFrameHeight; |
| | | |
| | | //if(nEndFrame != stFrame.nFrameIdx) |
| | | // return FALSE; |
| | | //if(nEndFrame != stFrame.nFrameIdx) |
| | | // return FALSE; |
| | | |
| | | g_pLog->DisplayMessage(_T("Measure Start %s - %d"),g_SideName[(int) emDim],stFrame.nFrameIdx); |
| | | g_pLog->DisplayMessage(_T("Measure Start %s - %d"), g_SideName[(int)emDim], stFrame.nFrameIdx); |
| | | |
| | | // Corner.. |
| | | Measure_TopCorner(iThread, emDim, stFrame); |
| | | |
| | | Measure_BotCorner(iThread, emDim, stFrame); |
| | | |
| | | if(pSideData->m_bFindGlassEndLine == FALSE) // Side Line篮 End Line 茫篮 Frame 捞 螟沥 茄促.. |
| | | if (pSideData->m_bFindGlassEndLine == FALSE) // Side Line은 End Line 찾은 Frame 이 측정 한다.. |
| | | return FALSE; |
| | | |
| | | g_pLog->DisplayMessage(_T("Side Measure Start %s - %d"),g_SideName[(int) emDim],stFrame.nFrameIdx); |
| | | g_pLog->DisplayMessage(_T("Side Measure Start %s - %d"), g_SideName[(int)emDim], stFrame.nFrameIdx); |
| | | // Side.. |
| | | Measure_Side(iThread, emDim, stFrame); |
| | | |
| | | g_pLog->DisplayMessage(_T("Side Measure End %s - %d"),g_SideName[(int) emDim],stFrame.nFrameIdx); |
| | | g_pLog->DisplayMessage(_T("Side Measure End %s - %d"), g_SideName[(int)emDim], stFrame.nFrameIdx); |
| | | |
| | | return TRUE; |
| | | } |
| | | |
| | | BOOL CInspectCamera::Measure_Side(int iThread,DimensionDir emDim, stFrameIndex stFrame) |
| | | BOOL CInspectCamera::Measure_Side(int iThread, DimensionDir emDim, stFrameIndex stFrame) |
| | | { |
| | | if(m_pGlassData == NULL || m_pRecipe == NULL) |
| | | if (m_pGlassData == NULL || m_pRecipe == NULL) |
| | | return FALSE; |
| | | |
| | | CSide_Data* pSideData = m_pGlassData->GetSideData(emDim); |
| | | CSIDE_PARM* pSideParam = &m_pRecipe->m_SideParam[(int) emDim]; |
| | | CSide_Data* pSideData = m_pGlassData->GetSideData(emDim); |
| | | CSIDE_PARM* pSideParam = &m_pRecipe->m_SideParam[(int)emDim]; |
| | | |
| | | if(pSideData == NULL || pSideParam == NULL) |
| | | if (pSideData == NULL || pSideParam == NULL) |
| | | return FALSE; |
| | | |
| | | if (pSideData->m_bTopMark_Find == FALSE || pSideData->m_bBotMark_Find == FALSE) |
| | | { |
| | | g_pLog->DisplayMessage(_T("Error : [%s] Top Align Mark or Bottom Align Mark Y is not detected.. [Fail to Measure Edge to Align Mark Line]"), g_SideName[(int) emDim]); |
| | | g_pLog->DisplayMessage(_T("Error : [%s] Top Align Mark or Bottom Align Mark Y is not detected.. [Fail to Measure Edge to Align Mark Line]"), g_SideName[(int)emDim]); |
| | | return FALSE; |
| | | } |
| | | |
| | | /////////////////////////////////////////////////////////////////////////////////////// |
| | | #if HALCON_VISION_KEY |
| | | //Set Info, 将MARK信息输入到SDK |
| | | //Set Info, 쉥MARK斤口渴흙돕SDK |
| | | CBlSideData* pBlSideData = BlVision_GetVisionRecipe()->getSideData(emDim); // ->m_bInspection_Complete = TRUE; |
| | | pBlSideData->m_bInspection_Complete = TRUE; |
| | | pBlSideData->m_dPixelSizeX = pSideData->m_dPixelSizeX; |
| | |
| | | double distX = GetPixelToUm_X(ptTopAlignMark.x - ptBottomAlignMark.x); |
| | | double distY = GetPixelToUm_Y(ptTopAlignMark.y - ptBottomAlignMark.y); |
| | | double dTopAlignToBottomAlignDistance = sqrt((distX * distX) + (distY * distY)); |
| | | |
| | | |
| | | double dGlassTilt_Radian = 0.0; |
| | | if (distX != 0.0) |
| | | dGlassTilt_Radian = atan(distX / distY); |
| | |
| | | |
| | | for (int nMeasurePointIdx = 0; nMeasurePointIdx < nMeasureCount; nMeasurePointIdx++) |
| | | { |
| | | if(MAX_SIDE_DIMENSION_MEASURE_COUNT <= nMeasurePointIdx) |
| | | if (MAX_SIDE_DIMENSION_MEASURE_COUNT <= nMeasurePointIdx) |
| | | break; |
| | | if(pSideData->m_bSideMeasureLine[nMeasurePointIdx] == TRUE) |
| | | if (pSideData->m_bSideMeasureLine[nMeasurePointIdx] == TRUE) |
| | | continue; |
| | | |
| | | double dMeasurePointPosX_um = sin(dGlassTilt_Radian) * pSideParam->m_nSideDimensionPos_TopMarkToDistance_um[nMeasurePointIdx]; |
| | | double dMeasurePointPosY_um = cos(dGlassTilt_Radian) * pSideParam->m_nSideDimensionPos_TopMarkToDistance_um[nMeasurePointIdx]; |
| | | |
| | | int nMeasurePointPosX = ptTopAlignMark.x + (int) GetUmToPixel_X(dMeasurePointPosX_um); |
| | | int nMeasurePointPosY = ptTopAlignMark.y + (int) GetUmToPixel_Y(dMeasurePointPosY_um); |
| | | int nMeasurePointPosX = ptTopAlignMark.x + (int)GetUmToPixel_X(dMeasurePointPosX_um); |
| | | int nMeasurePointPosY = ptTopAlignMark.y + (int)GetUmToPixel_Y(dMeasurePointPosY_um); |
| | | |
| | | double dEndPointPosX_um = cos(dGlassTilt_Radian) * nTopEdgeToMark_X_um * -1.0; |
| | | double dEndPointPosY_um = sin(dGlassTilt_Radian) * nTopEdgeToMark_X_um;// * -1.0; |
| | | |
| | | int nEndPointPosX = nMeasurePointPosX + (int) GetUmToPixel_X(dEndPointPosX_um); |
| | | int nEndPointPosY = nMeasurePointPosY + (int) GetUmToPixel_Y(dEndPointPosY_um); |
| | | int nEndPointPosX = nMeasurePointPosX + (int)GetUmToPixel_X(dEndPointPosX_um); |
| | | int nEndPointPosY = nMeasurePointPosY + (int)GetUmToPixel_Y(dEndPointPosY_um); |
| | | |
| | | int nFindRangeX = 100; |
| | | int nFindRangeY = 20; |
| | |
| | | CRect rtFindPos = CRect(nEndPointPosX, nEndPointPosY, nEndPointPosX, nEndPointPosY); |
| | | rtFindPos.InflateRect(nFindRangeX, nFindRangeY); |
| | | |
| | | if(rtFindPos.left < 0) rtFindPos.left = 0; |
| | | if(m_nFrameWidth <= rtFindPos.right) rtFindPos.right = m_nFrameWidth-1; |
| | | if(rtFindPos.top < pSideData->m_nGlassStartLine) rtFindPos.top = pSideData->m_nGlassStartLine; |
| | | if(pSideData->m_nGlassEndLine < rtFindPos.bottom) rtFindPos.bottom = pSideData->m_nGlassEndLine; |
| | | if (rtFindPos.left < 0) rtFindPos.left = 0; |
| | | if (m_nFrameWidth <= rtFindPos.right) rtFindPos.right = m_nFrameWidth - 1; |
| | | if (rtFindPos.top < pSideData->m_nGlassStartLine) rtFindPos.top = pSideData->m_nGlassStartLine; |
| | | if (pSideData->m_nGlassEndLine < rtFindPos.bottom) rtFindPos.bottom = pSideData->m_nGlassEndLine; |
| | | |
| | | if(rtFindPos.left >= rtFindPos.right) |
| | | if (rtFindPos.left >= rtFindPos.right) |
| | | continue; |
| | | if(rtFindPos.top >= rtFindPos.bottom) |
| | | if (rtFindPos.top >= rtFindPos.bottom) |
| | | continue; |
| | | if(rtFindPos.Width() <= 20 || rtFindPos.Height() <= 2) |
| | | continue; |
| | | if (rtFindPos.Width() <= 20 || rtFindPos.Height() <= 2) |
| | | continue; |
| | | |
| | | LPBYTE pFrameBuffer = m_pGrabber->GetFrameHeader(stFrame.nScanIdx, 0); |
| | | |
| | | if(pFrameBuffer == NULL) |
| | | if (pFrameBuffer == NULL) |
| | | continue; |
| | | |
| | | COwnerBuffer pFindImage = COwnerBuffer(rtFindPos.Width(), rtFindPos.Height()); |
| | | |
| | | for(int i=0; i<rtFindPos.Height(); i++) |
| | | for (int i = 0; i < rtFindPos.Height(); i++) |
| | | memcpy(pFindImage.GetDataAddress(0, i), pFrameBuffer + (m_nFrameWidth * (rtFindPos.top + i)) + rtFindPos.left, rtFindPos.Width()); |
| | | |
| | | //{ |
| | | // CString str; |
| | | // str.Format(_T("D:\\Inspection\\DebugFullImg\\Side\\Org_%s_%02d.bmp"),g_SideName[(int) emDim],nMeasurePointIdx); |
| | | // CBufferAttach attach(str); |
| | | // attach.AttachToFile(pFindImage); |
| | | //} |
| | | //{ |
| | | // CString str; |
| | | // str.Format(_T("D:\\Inspection\\DebugFullImg\\Side\\Org_%s_%02d.bmp"),g_SideName[(int) emDim],nMeasurePointIdx); |
| | | // CBufferAttach attach(str); |
| | | // attach.AttachToFile(pFindImage); |
| | | //} |
| | | |
| | | int nSideLineThres = m_pRecipe->m_SideParam[(int) emDim].m_nSideLineThreshold; |
| | | int nChamferLineThres = m_pRecipe->m_SideParam[(int) emDim].m_nChamferLineThreshold; |
| | | int nSideLineThres = m_pRecipe->m_SideParam[(int)emDim].m_nSideLineThreshold; |
| | | int nChamferLineThres = m_pRecipe->m_SideParam[(int)emDim].m_nChamferLineThreshold; |
| | | |
| | | CRect rtFindROI = CRect(0,0,rtFindPos.Width()-1, rtFindPos.Height()-1); |
| | | |
| | | CRect rtFindROI = CRect(0, 0, rtFindPos.Width() - 1, rtFindPos.Height() - 1); |
| | | |
| | | int nFindEdgeLine = -1; |
| | | int nFindChamferLine = -1; |
| | | |
| | |
| | | rtFindROI.left = nFindEdgeLine + 3; |
| | | |
| | | CChamferInspect chamferIns; |
| | | COwnerBuffer ImgInsBin; |
| | | chamferIns.Binarization(pFindImage,ImgInsBin,nChamferLineThres); |
| | | COwnerBuffer ImgInsBin; |
| | | chamferIns.Binarization(pFindImage, ImgInsBin, nChamferLineThres); |
| | | |
| | | //{ |
| | | // CString str; |
| | | // str.Format(_T("D:\\Inspection\\DebugFullImg\\Side\\Bin_%s_%02d.bmp"),g_SideName[(int) emDim],nMeasurePointIdx); |
| | | // CBufferAttach attach(str); |
| | | // attach.AttachToFile(ImgInsBin); |
| | | //} |
| | | //{ |
| | | // CString str; |
| | | // str.Format(_T("D:\\Inspection\\DebugFullImg\\Side\\Bin_%s_%02d.bmp"),g_SideName[(int) emDim],nMeasurePointIdx); |
| | | // CBufferAttach attach(str); |
| | | // attach.AttachToFile(ImgInsBin); |
| | | //} |
| | | double dLine = -1; |
| | | chamferIns.FindRightLine_Bin(ImgInsBin,nFindEdgeLine,dLine); |
| | | chamferIns.FindRightLine_Bin(ImgInsBin, nFindEdgeLine, dLine); |
| | | nFindChamferLine = (int)dLine; |
| | | |
| | | //EdgeFind.FindEdge_ToRightROI(&pFindImage, nFindChamferLine, DEFECT_EDGE_AUTO_PITCH, nChamferLineThres, DEFECT_EDGE_AUTO_RATIO, 0, rtFindROI); |
| | | |
| | | |
| | | int nSideLine = rtFindPos.left + nFindEdgeLine; |
| | | int nChamferLine = rtFindPos.left + ((nFindChamferLine != -1 && pSideParam->m_bSideChamfer_Use[nMeasurePointIdx] == TRUE) ? nFindChamferLine : nFindEdgeLine); |
| | | |
| | | // Frame俊辑 措钎肺 茫篮吧肺 螟沥 搬苞肺 静霸 沁绰单.... 捞固瘤俊辑 促矫 茫档废 荐沥捞 鞘夸..且鳖?? |
| | | // Frame에서 대표로 찾은걸로 측정 결과로 쓰게 했는데.... 이미지에서 다시 찾도록 수정이 필요..할까?? |
| | | int nFrameIdx = (int)(nEndPointPosY / m_nFrameHeight); |
| | | /* |
| | | int nSideLine = pSideData->m_nSideLineFrame[nFrameIdx]; |
| | |
| | | |
| | | pSideData->m_ptSideMeasure_ChamferLine[nMeasurePointIdx] = ptEnd_ChamferLine; // Measure Chamfer Line.. |
| | | pSideData->m_dSideMeasrue_Chamfer_Result_mm[nMeasurePointIdx] = dDistance_ChamferLine_mm; |
| | | |
| | | |
| | | pSideData->m_bSideMeasureLine[nMeasurePointIdx] = TRUE; |
| | | |
| | | // 烙矫肺 阜澜. SW 促款. |
| | | // 임시로 막음. SW 다운. |
| | | // continue; |
| | | |
| | | // Dimension |
| | | double dTempValue = pSideParam->m_dSideDimensionSpec_mm_Std[nMeasurePointIdx]; |
| | | if(pSideParam->m_bSideDimension_Use[nMeasurePointIdx] == TRUE && dTempValue >= 0) |
| | | if (pSideParam->m_bSideDimension_Use[nMeasurePointIdx] == TRUE && dTempValue >= 0) |
| | | { |
| | | double dStd_mm = pSideParam->m_dSideDimensionSpec_mm_Std[nMeasurePointIdx]; |
| | | double dMin_mm = (dStd_mm - abs(pSideParam->m_dSideDimensionSpec_mm_Min[nMeasurePointIdx])); |
| | |
| | | |
| | | double dResult_mm = dDistance_CutLine_mm; |
| | | |
| | | if(dResult_mm < dMin_mm || dMax_mm < dResult_mm) |
| | | if (dResult_mm < dMin_mm || dMax_mm < dResult_mm) |
| | | { |
| | | pSideData->m_nSideMeasure_CutLine_Status[nMeasurePointIdx] = 2; // NG |
| | | |
| | |
| | | measureDefect.m_nCamID = m_iCamera; |
| | | measureDefect.m_nScanIdx = stFrame.nScanIdx; |
| | | measureDefect.m_nGlassStartLine = pSideData->m_nGlassStartLine; |
| | | measureDefect.m_nSideIdx = (int) emDim; |
| | | measureDefect.m_nSideIdx = (int)emDim; |
| | | measureDefect.m_DefectLoc = DefectLoc_Measure_Dimension; |
| | | measureDefect.m_ptDefectPos_pxl = ptEnd_CutLine; // CPoint(nEndPointPosX, nEndPointPosY); |
| | | measureDefect.m_rtDefectPos_pxl = CRect(ptEnd_CutLine.x - 16, ptEnd_CutLine.y - 16, ptEnd_CutLine.x + 16, ptEnd_CutLine.y + 16); |
| | | |
| | | g_pLog->DisplayMessage(_T("Measure Glass Line NG Start %s-%d : %d,%d"),g_SideName[(int) emDim],nMeasurePointIdx,measureDefect.m_ptDefectPos_pxl.x,measureDefect.m_ptDefectPos_pxl.y); |
| | | g_pLog->DisplayMessage(_T("Measure Glass Line NG Start %s-%d : %d,%d"), g_SideName[(int)emDim], nMeasurePointIdx, measureDefect.m_ptDefectPos_pxl.x, measureDefect.m_ptDefectPos_pxl.y); |
| | | |
| | | m_pDefectControl->ExtractDefect_Measure(emDim, m_iCamera, stFrame.nScanIdx, measureDefect, dDistance_CutLine_mm, dResult_mm); |
| | | |
| | | g_pLog->DisplayMessage(_T("Measure Glass Line NG End %s-%d : %d,%d"),g_SideName[(int) emDim],nMeasurePointIdx,measureDefect.m_ptDefectPos_pxl.x,measureDefect.m_ptDefectPos_pxl.y); |
| | | g_pLog->DisplayMessage(_T("Measure Glass Line NG End %s-%d : %d,%d"), g_SideName[(int)emDim], nMeasurePointIdx, measureDefect.m_ptDefectPos_pxl.x, measureDefect.m_ptDefectPos_pxl.y); |
| | | } |
| | | else |
| | | pSideData->m_nSideMeasure_CutLine_Status[nMeasurePointIdx] = 1; // OK |
| | | } |
| | | else if (pSideParam->m_bSideDimension_Use[nMeasurePointIdx] == TRUE && dTempValue < -0.01) { |
| | | #if HALCON_VISION_KEY |
| | | //切割线的长度计算, jiang, 09-27, 2024 |
| | | //학몇窟돨낀똑셕炬, jiang, 09-27, 2024 |
| | | int nThres = pSideParam->m_nSideDimensionSpec_Thres[nMeasurePointIdx]; |
| | | int toLineDist = 1000 * pSideParam->m_dSideDimensionSpec_mm_Std[nMeasurePointIdx]; |
| | | int toTopY = pSideParam->m_nSideDimensionPos_TopMarkToDistance_um[nMeasurePointIdx]; |
| | |
| | | } |
| | | |
| | | // Chamfer |
| | | if(pSideParam->m_bSideChamfer_Use[nMeasurePointIdx] == TRUE) |
| | | if (pSideParam->m_bSideChamfer_Use[nMeasurePointIdx] == TRUE) |
| | | { |
| | | double dStd_mm = pSideParam->m_dSideChamfer_Spec_mm_Std[nMeasurePointIdx]; |
| | | double dMin_mm = (dStd_mm - abs(pSideParam->m_dSideChamfer_Spec_mm_Min[nMeasurePointIdx])); |
| | |
| | | |
| | | double dResult_mm = dDistance_ChamferLine_mm; |
| | | |
| | | if(dResult_mm < dMin_mm || dMax_mm < dResult_mm) |
| | | if (dResult_mm < dMin_mm || dMax_mm < dResult_mm) |
| | | { |
| | | pSideData->m_nSideMeasure_ChamferLine_Status[nMeasurePointIdx] = 2; // NG |
| | | |
| | |
| | | measureDefect.m_nCamID = m_iCamera; |
| | | measureDefect.m_nScanIdx = stFrame.nScanIdx; |
| | | measureDefect.m_nGlassStartLine = pSideData->m_nGlassStartLine; |
| | | measureDefect.m_nSideIdx = (int) emDim; |
| | | measureDefect.m_nSideIdx = (int)emDim; |
| | | measureDefect.m_DefectLoc = DefectLoc_Measure_Chamfer; |
| | | measureDefect.m_ptDefectPos_pxl = CPoint(nEndPointPosX, nEndPointPosY); |
| | | measureDefect.m_rtDefectPos_pxl = CRect(nEndPointPosX - 100, nEndPointPosY - 100, nEndPointPosX + 100, nEndPointPosY + 100); |
| | | |
| | | g_pLog->DisplayMessage(_T("Measure Glass NG Chamfer Start %s-%d : %d,%d"),g_SideName[(int) emDim],nMeasurePointIdx,measureDefect.m_ptDefectPos_pxl.x,measureDefect.m_ptDefectPos_pxl.y); |
| | | g_pLog->DisplayMessage(_T("Measure Glass NG Chamfer Start %s-%d : %d,%d"), g_SideName[(int)emDim], nMeasurePointIdx, measureDefect.m_ptDefectPos_pxl.x, measureDefect.m_ptDefectPos_pxl.y); |
| | | |
| | | m_pDefectControl->ExtractDefect_Measure(emDim, m_iCamera, stFrame.nScanIdx, measureDefect, dDistance_CutLine_mm, dResult_mm); |
| | | |
| | | g_pLog->DisplayMessage(_T("Measure Glass NG Chamfer End %s-%d : %d,%d"),g_SideName[(int) emDim],nMeasurePointIdx,measureDefect.m_ptDefectPos_pxl.x,measureDefect.m_ptDefectPos_pxl.y); |
| | | g_pLog->DisplayMessage(_T("Measure Glass NG Chamfer End %s-%d : %d,%d"), g_SideName[(int)emDim], nMeasurePointIdx, measureDefect.m_ptDefectPos_pxl.x, measureDefect.m_ptDefectPos_pxl.y); |
| | | |
| | | /* |
| | | // Make Defect |
| | |
| | | pSideData->m_nSideMeasure_ChamferLine_Status[nMeasurePointIdx] = 1; // OK |
| | | } |
| | | |
| | | g_pLog->DisplayMessage(_T("Measure End %s-%d : %d,%d,%d,%d"),g_SideName[(int) emDim],nMeasurePointIdx,rtFindPos.left,rtFindPos.top,rtFindPos.right,rtFindPos.bottom); |
| | | g_pLog->DisplayMessage(_T("Measure End %s-%d : %d,%d,%d,%d"), g_SideName[(int)emDim], nMeasurePointIdx, rtFindPos.left, rtFindPos.top, rtFindPos.right, rtFindPos.bottom); |
| | | } |
| | | |
| | | return TRUE; |
| | | } |
| | | |
| | | BOOL CInspectCamera::Measure_TopCorner(int iThread,DimensionDir emDim, stFrameIndex stFrame) |
| | | BOOL CInspectCamera::Measure_TopCorner(int iThread, DimensionDir emDim, stFrameIndex stFrame) |
| | | { |
| | | if(m_pGlassData == NULL || m_pRecipe == NULL) |
| | | if (m_pGlassData == NULL || m_pRecipe == NULL) |
| | | return FALSE; |
| | | |
| | | CSide_Data* pSideData = m_pGlassData->GetSideData(emDim); |
| | | CSIDE_PARM* pSideParam = &m_pRecipe->m_SideParam[(int) emDim]; |
| | | CSide_Data* pSideData = m_pGlassData->GetSideData(emDim); |
| | | CSIDE_PARM* pSideParam = &m_pRecipe->m_SideParam[(int)emDim]; |
| | | |
| | | if(pSideData == NULL || pSideParam == NULL) |
| | | if (pSideData == NULL || pSideParam == NULL) |
| | | return FALSE; |
| | | |
| | | if(pSideParam->m_bTopCornerMeasureSize == FALSE) |
| | | if (pSideParam->m_bTopCornerMeasureSize == FALSE) |
| | | return FALSE; |
| | | |
| | | if (pSideData->m_bTopCorner_Find == FALSE) |
| | |
| | | |
| | | int nTopCornerType = pSideData->m_nTopCornerShape; |
| | | |
| | | if(nTopCornerType == (int) 1) return Measure_TopCorner_CCut(iThread, emDim, stFrame); |
| | | else if(nTopCornerType == (int) 2) return Measure_TopCorner_RCut(iThread, emDim, stFrame); |
| | | if (nTopCornerType == (int)1) return Measure_TopCorner_CCut(iThread, emDim, stFrame); |
| | | else if (nTopCornerType == (int)2) return Measure_TopCorner_RCut(iThread, emDim, stFrame); |
| | | else pSideData->m_bTopCorner_Measure = TRUE; |
| | | |
| | | return TRUE; |
| | | } |
| | | |
| | | BOOL CInspectCamera::Measure_TopCorner_CCut(int iThread,DimensionDir emDim, stFrameIndex stFrame) |
| | | BOOL CInspectCamera::Measure_TopCorner_CCut(int iThread, DimensionDir emDim, stFrameIndex stFrame) |
| | | { |
| | | if(m_pGlassData == NULL || m_pRecipe == NULL) |
| | | if (m_pGlassData == NULL || m_pRecipe == NULL) |
| | | return FALSE; |
| | | |
| | | CSide_Data* pSideData = m_pGlassData->GetSideData(emDim); |
| | | CSIDE_PARM* pSideParam = &m_pRecipe->m_SideParam[(int) emDim]; |
| | | CSide_Data* pSideData = m_pGlassData->GetSideData(emDim); |
| | | CSIDE_PARM* pSideParam = &m_pRecipe->m_SideParam[(int)emDim]; |
| | | |
| | | if(pSideData == NULL || pSideParam == NULL) |
| | | if (pSideData == NULL || pSideParam == NULL) |
| | | return FALSE; |
| | | |
| | | CRect rtTopCornerArea = pSideData->m_rtTopCornerArea; |
| | | |
| | | rtTopCornerArea.InflateRect(50,50); |
| | | |
| | | rtTopCornerArea.InflateRect(50, 50); |
| | | |
| | | int iCornerFrame = rtTopCornerArea.bottom/m_nFrameHeight; |
| | | |
| | | if(iCornerFrame > stFrame.nFrameIdx) |
| | | int iCornerFrame = rtTopCornerArea.bottom / m_nFrameHeight; |
| | | |
| | | if (iCornerFrame > stFrame.nFrameIdx) |
| | | return FALSE; |
| | | |
| | | // Corner 八荤 父甸扁.. |
| | | if(FindCorner(iThread,emDim,stFrame,0,rtTopCornerArea) == TRUE) |
| | | // Corner 검사 만들기.. |
| | | if (FindCorner(iThread, emDim, stFrame, 0, rtTopCornerArea) == TRUE) |
| | | { |
| | | double dXSizeStd_um = pSideParam->m_nTopCorner_Measure_Judge_Std_um_X; |
| | | double dXSizeMin_um = pSideParam->m_nTopCorner_Measure_Judge_Min_um_X; |
| | |
| | | double dYSizeMax_um = pSideParam->m_nTopCorner_Measure_Judge_Max_um_Y; |
| | | int nOpt = pSideParam->m_nTopCorner_Measure_Judge_OR_AND; |
| | | |
| | | if(nOpt == 0) |
| | | if (nOpt == 0) |
| | | return FALSE; |
| | | |
| | | double dResultWidth_um = pSideData->m_nTopCornerWidth; |
| | | double dResultHeight_um = pSideData->m_nTopCornerHeight; |
| | | |
| | | pSideData->m_bTopCornerMeasureResult = TRUE; |
| | | if(nOpt == 1) // or |
| | | if (nOpt == 1) // or |
| | | { |
| | | if( (dResultWidth_um < dXSizeStd_um-dXSizeMin_um || dResultWidth_um > dXSizeStd_um+dXSizeMax_um) || (dResultHeight_um < dYSizeStd_um-dYSizeMin_um || dResultHeight_um > dYSizeStd_um+dYSizeMax_um)) |
| | | if ((dResultWidth_um < dXSizeStd_um - dXSizeMin_um || dResultWidth_um > dXSizeStd_um + dXSizeMax_um) || (dResultHeight_um < dYSizeStd_um - dYSizeMin_um || dResultHeight_um > dYSizeStd_um + dYSizeMax_um)) |
| | | { |
| | | pSideData->m_bTopCornerMeasureResult = FALSE; // NG |
| | | } |
| | | } |
| | | else // and |
| | | { |
| | | if( (dResultWidth_um < dXSizeStd_um-dXSizeMin_um || dResultWidth_um > dXSizeStd_um+dXSizeMax_um) && (dResultHeight_um < dYSizeStd_um-dYSizeMin_um || dResultHeight_um > dYSizeStd_um+dYSizeMax_um)) |
| | | if ((dResultWidth_um < dXSizeStd_um - dXSizeMin_um || dResultWidth_um > dXSizeStd_um + dXSizeMax_um) && (dResultHeight_um < dYSizeStd_um - dYSizeMin_um || dResultHeight_um > dYSizeStd_um + dYSizeMax_um)) |
| | | { |
| | | pSideData->m_bTopCornerMeasureResult = FALSE; // NG |
| | | } |
| | | } |
| | | |
| | | if(pSideData->m_bTopCornerMeasureResult == FALSE) |
| | | if (pSideData->m_bTopCornerMeasureResult == FALSE) |
| | | { |
| | | // Make Defect |
| | | CDefect_Info measureDefect; |
| | |
| | | measureDefect.m_nCamID = m_iCamera; |
| | | measureDefect.m_nScanIdx = stFrame.nScanIdx; |
| | | measureDefect.m_nGlassStartLine = pSideData->m_nGlassStartLine; |
| | | measureDefect.m_nSideIdx = (int) emDim; |
| | | measureDefect.m_nSideIdx = (int)emDim; |
| | | measureDefect.m_DefectLoc = DefectLoc_Measure_Corner; |
| | | measureDefect.m_ptDefectPos_pxl = pSideData->m_rtTopCornerResult[1].CenterPoint(); |
| | | measureDefect.m_rtDefectPos_pxl = CRect(measureDefect.m_ptDefectPos_pxl.x - 16, measureDefect.m_ptDefectPos_pxl.y - 16, measureDefect.m_ptDefectPos_pxl.x + 16, measureDefect.m_ptDefectPos_pxl.y + 16); |
| | | |
| | | g_pLog->DisplayMessage(_T("Measure Top Corner NG Start %s : %d,%d"),g_SideName[(int) emDim],measureDefect.m_ptDefectPos_pxl.x,measureDefect.m_ptDefectPos_pxl.y); |
| | | g_pLog->DisplayMessage(_T("Measure Top Corner NG Start %s : %d,%d"), g_SideName[(int)emDim], measureDefect.m_ptDefectPos_pxl.x, measureDefect.m_ptDefectPos_pxl.y); |
| | | |
| | | m_pDefectControl->ExtractDefect_Measure(emDim, m_iCamera, stFrame.nScanIdx, measureDefect, dResultWidth_um, dResultHeight_um); |
| | | |
| | | g_pLog->DisplayMessage(_T("Measure Top Corner NG End %s : %d,%d"),g_SideName[(int) emDim],measureDefect.m_ptDefectPos_pxl.x,measureDefect.m_ptDefectPos_pxl.y); |
| | | g_pLog->DisplayMessage(_T("Measure Top Corner NG End %s : %d,%d"), g_SideName[(int)emDim], measureDefect.m_ptDefectPos_pxl.x, measureDefect.m_ptDefectPos_pxl.y); |
| | | } |
| | | |
| | | |
| | | } |
| | | |
| | | |
| | | |
| | | return TRUE; |
| | | } |
| | | |
| | | BOOL CInspectCamera::FindCorner(int iThread,DimensionDir emDim, stFrameIndex stFrame,int nPos,CRect rtConnerRoi) |
| | | { |
| | | g_pLog->DisplayMessage(_T("%s Corner pos %d, frame %d - %d,%d,%d,%d"),g_SideName[(int) emDim],nPos,stFrame.nFrameIdx,rtConnerRoi.left,rtConnerRoi.top,rtConnerRoi.right,rtConnerRoi.bottom); |
| | | BOOL CInspectCamera::FindCorner(int iThread, DimensionDir emDim, stFrameIndex stFrame, int nPos, CRect rtConnerRoi) |
| | | { |
| | | g_pLog->DisplayMessage(_T("%s Corner pos %d, frame %d - %d,%d,%d,%d"), g_SideName[(int)emDim], nPos, stFrame.nFrameIdx, rtConnerRoi.left, rtConnerRoi.top, rtConnerRoi.right, rtConnerRoi.bottom); |
| | | |
| | | CSide_Data* pSideData = m_pGlassData->GetSideData(emDim); |
| | | CSIDE_PARM* pSideParam = &m_pRecipe->m_SideParam[(int) emDim]; |
| | | CSide_Data* pSideData = m_pGlassData->GetSideData(emDim); |
| | | CSIDE_PARM* pSideParam = &m_pRecipe->m_SideParam[(int)emDim]; |
| | | |
| | | // 1. Make ROI |
| | | rtConnerRoi.left = (rtConnerRoi.left < 0) ? 0 : rtConnerRoi.left; |
| | | rtConnerRoi.top = (rtConnerRoi.top < 0) ? 0 : rtConnerRoi.top; |
| | | rtConnerRoi.right = (rtConnerRoi.right >= m_nFrameWidth) ? m_nFrameWidth-1 : rtConnerRoi.right; |
| | | rtConnerRoi.right = (rtConnerRoi.right >= m_nFrameWidth) ? m_nFrameWidth - 1 : rtConnerRoi.right; |
| | | |
| | | // 2. Get Image Buffer |
| | | BYTE* pBuffer = m_pGrabber->GetFrameHeaderLine(stFrame.nScanIdx, rtConnerRoi.top); |
| | | IplImage* pConnerOriginImage = cvCreateImage(cvSize(rtConnerRoi.Width(), rtConnerRoi.Height()), 8, 1); |
| | | BYTE* pBuffer = m_pGrabber->GetFrameHeaderLine(stFrame.nScanIdx, rtConnerRoi.top); |
| | | IplImage* pConnerOriginImage = cvCreateImage(cvSize(rtConnerRoi.Width(), rtConnerRoi.Height()), 8, 1); |
| | | IplImage* pConnerEdgeImage; |
| | | IplImage* pConnerEdgeOutLineImage = cvCreateImage(cvSize(rtConnerRoi.Width(), rtConnerRoi.Height()), 8, 1); |
| | | IplImage* pConnerEdgeOutLineImage = cvCreateImage(cvSize(rtConnerRoi.Width(), rtConnerRoi.Height()), 8, 1); |
| | | |
| | | if(pBuffer == NULL) |
| | | if (pBuffer == NULL) |
| | | return FALSE; |
| | | |
| | | for(int i=0; i<rtConnerRoi.Height(); i++) |
| | | memcpy(pConnerOriginImage->imageData+(i*pConnerOriginImage->widthStep), (char*) &pBuffer[rtConnerRoi.left + (i*m_nFrameWidth)], rtConnerRoi.Width()); |
| | | for (int i = 0; i < rtConnerRoi.Height(); i++) |
| | | memcpy(pConnerOriginImage->imageData + (i * pConnerOriginImage->widthStep), (char*)&pBuffer[rtConnerRoi.left + (i * m_nFrameWidth)], rtConnerRoi.Width()); |
| | | |
| | | pConnerEdgeImage = cvCloneImage(pConnerOriginImage); |
| | | |
| | |
| | | |
| | | BOOL bFind = FALSE; |
| | | int nContinueCount = 5; |
| | | UINT nTarget = 0; |
| | | UINT nCompare = 0; |
| | | int nDiff = 0; |
| | | UINT nTarget = 0; |
| | | UINT nCompare = 0; |
| | | int nDiff = 0; |
| | | |
| | | int nEdgeFilter; |
| | | double dCornerEdgeTh1; |
| | | |
| | | if(nPos == 0) |
| | | if (nPos == 0) |
| | | { |
| | | nEdgeFilter = pSideParam->m_nTopCornerEdgeFilterSize; |
| | | dCornerEdgeTh1 = pSideParam->m_nTopCornerEdgeThreshold; |
| | |
| | | dCornerEdgeTh1 = pSideParam->m_nBottomCornerEdgeThreshold; |
| | | } |
| | | |
| | | if(nEdgeFilter % 2 == 0) |
| | | if (nEdgeFilter % 2 == 0) |
| | | nEdgeFilter = nEdgeFilter - 1; |
| | | |
| | | if(1 < nEdgeFilter) |
| | | if (1 < nEdgeFilter) |
| | | cvSmooth(pConnerEdgeImage, pConnerEdgeImage, CV_MEDIAN, nEdgeFilter); |
| | | |
| | | |
| | | dCornerEdgeTh1 *= 10.; |
| | | dCornerEdgeTh1 *= 10.; |
| | | double dCornerEdgeTh2 = 40.0; |
| | | int sigma=5; |
| | | int sigma = 5; |
| | | |
| | | cvCanny(pConnerEdgeImage, pConnerEdgeImage, dCornerEdgeTh1, dCornerEdgeTh2, sigma); |
| | | |
| | | // Side |
| | | for(int i=0; i<pConnerEdgeImage->height; i++) |
| | | for (int i = 0; i < pConnerEdgeImage->height; i++) |
| | | { |
| | | for(int j=0; j<pConnerEdgeImage->width; j++) |
| | | for (int j = 0; j < pConnerEdgeImage->width; j++) |
| | | { |
| | | nTarget = (UINT) pConnerEdgeImage->imageData[pConnerOriginImage->widthStep*i + j]; |
| | | nTarget = (UINT)pConnerEdgeImage->imageData[pConnerOriginImage->widthStep * i + j]; |
| | | |
| | | if(nTarget != 0) |
| | | if (nTarget != 0) |
| | | { |
| | | pConnerEdgeOutLineImage->imageData[pConnerOriginImage->widthStep*i + j] = 255; |
| | | pConnerEdgeOutLineImage->imageData[pConnerOriginImage->widthStep * i + j] = 255; |
| | | break; |
| | | } |
| | | } |
| | | } |
| | | |
| | | // Top, Bottom |
| | | if(nPos == 0) |
| | | if (nPos == 0) |
| | | { |
| | | for(int i=0; i<pConnerEdgeImage->width; i++) |
| | | for (int i = 0; i < pConnerEdgeImage->width; i++) |
| | | { |
| | | for(int j=0; j<pConnerEdgeImage->height; j++) |
| | | for (int j = 0; j < pConnerEdgeImage->height; j++) |
| | | { |
| | | nTarget = (UINT) pConnerEdgeImage->imageData[pConnerOriginImage->widthStep*j + i]; |
| | | nTarget = (UINT)pConnerEdgeImage->imageData[pConnerOriginImage->widthStep * j + i]; |
| | | |
| | | if(nTarget != 0) |
| | | if (nTarget != 0) |
| | | { |
| | | pConnerEdgeOutLineImage->imageData[pConnerEdgeOutLineImage->widthStep*j + i] = 255; |
| | | pConnerEdgeOutLineImage->imageData[pConnerEdgeOutLineImage->widthStep * j + i] = 255; |
| | | break; |
| | | } |
| | | } |
| | |
| | | } |
| | | else |
| | | { |
| | | for(int i=0; i<pConnerEdgeImage->width; i++) |
| | | for (int i = 0; i < pConnerEdgeImage->width; i++) |
| | | { |
| | | for(int j=0; j<pConnerEdgeImage->height; j++) |
| | | for (int j = 0; j < pConnerEdgeImage->height; j++) |
| | | { |
| | | nTarget = (UINT) pConnerEdgeImage->imageData[pConnerOriginImage->widthStep*(pConnerOriginImage->height- 1 -j) + i]; |
| | | nTarget = (UINT)pConnerEdgeImage->imageData[pConnerOriginImage->widthStep * (pConnerOriginImage->height - 1 - j) + i]; |
| | | |
| | | if(nTarget != 0) |
| | | if (nTarget != 0) |
| | | { |
| | | pConnerEdgeOutLineImage->imageData[pConnerEdgeOutLineImage->widthStep*(pConnerEdgeOutLineImage->height- 1 -j) + i] = 255; |
| | | pConnerEdgeOutLineImage->imageData[pConnerEdgeOutLineImage->widthStep * (pConnerEdgeOutLineImage->height - 1 - j) + i] = 255; |
| | | break; |
| | | } |
| | | } |
| | |
| | | |
| | | strTemp.Format(_T("Corner\\ConnerProcess_OutLine_%d.jpg"), nPos); |
| | | SaveDebugImage(emDim, stFrame, pConnerEdgeOutLineImage, strTemp); |
| | | |
| | | |
| | | |
| | | // 4. OutLine Projection Data |
| | | std::vector<int> vecProjectionX; |
| | |
| | | |
| | | int nValue; |
| | | |
| | | for(int i=0; i<rtConnerRoi.Height(); i++) |
| | | for (int i = 0; i < rtConnerRoi.Height(); i++) |
| | | { |
| | | for(int j=0; j<rtConnerRoi.Width(); j++) |
| | | for (int j = 0; j < rtConnerRoi.Width(); j++) |
| | | { |
| | | nValue = (int) pConnerEdgeOutLineImage->imageData[j+(i*pConnerEdgeOutLineImage->widthStep)]; |
| | | nValue = (int)pConnerEdgeOutLineImage->imageData[j + (i * pConnerEdgeOutLineImage->widthStep)]; |
| | | |
| | | if(pConnerEdgeOutLineImage->imageData[i*pConnerEdgeOutLineImage->widthStep + j] != 0) |
| | | if (pConnerEdgeOutLineImage->imageData[i * pConnerEdgeOutLineImage->widthStep + j] != 0) |
| | | { |
| | | vecProjectionX[j]++; |
| | | vecProjectionY[i]++; |
| | |
| | | // 5. Find Edge |
| | | CPoint ptConner[3]; |
| | | |
| | | int nMaxCount = -1; |
| | | int nMaxIdx = 0; |
| | | int nMaxCount = -1; |
| | | int nMaxIdx = 0; |
| | | |
| | | for(int i=0; i<rtConnerRoi.Width(); i++) |
| | | for (int i = 0; i < rtConnerRoi.Width(); i++) |
| | | { |
| | | if(nMaxCount < vecProjectionX[i]) |
| | | if (nMaxCount < vecProjectionX[i]) |
| | | { |
| | | nMaxIdx = i; |
| | | nMaxCount = vecProjectionX[i]; |
| | |
| | | } |
| | | ptConner[0].x = ptConner[1].x = ptConner[2].x = nMaxIdx; |
| | | |
| | | if(nPos == 0) |
| | | if (nPos == 0) |
| | | { |
| | | nMaxCount = -1; |
| | | nMaxIdx = 0; |
| | | nMaxCount = -1; |
| | | nMaxIdx = 0; |
| | | |
| | | for(int i=0; i<rtConnerRoi.Height(); i++) |
| | | for (int i = 0; i < rtConnerRoi.Height(); i++) |
| | | { |
| | | if(nMaxCount < vecProjectionY[i]) |
| | | if (nMaxCount < vecProjectionY[i]) |
| | | { |
| | | nMaxIdx = i; |
| | | nMaxCount = vecProjectionY[i]; |
| | |
| | | } |
| | | else |
| | | { |
| | | nMaxCount = -1; |
| | | nMaxIdx = 0; |
| | | nMaxCount = -1; |
| | | nMaxIdx = 0; |
| | | |
| | | for(int i=rtConnerRoi.Height()-1; 0 <= i; i--) |
| | | for (int i = rtConnerRoi.Height() - 1; 0 <= i; i--) |
| | | { |
| | | if(nMaxCount < vecProjectionY[i]) |
| | | if (nMaxCount < vecProjectionY[i]) |
| | | { |
| | | nMaxIdx = i; |
| | | nMaxCount = vecProjectionY[i]; |
| | |
| | | ptConner[0].y = ptConner[1].y = ptConner[2].y = nMaxIdx; |
| | | } |
| | | |
| | | double dCornerSizeY_Um = (double)pSideParam->m_nTopCornerSizeY_um; |
| | | int nCornerSizeY_Pixel = (int) GetUmToPixel_Y(dCornerSizeY_Um); |
| | | double dCornerSizeX_Um = (double) pSideParam->m_nTopCornerSizeX_um; |
| | | int nCornerSizeX_Pixel = (int) GetUmToPixel_X(dCornerSizeX_Um); |
| | | double dCornerSizeY_Um = (double)pSideParam->m_nTopCornerSizeY_um; |
| | | int nCornerSizeY_Pixel = (int)GetUmToPixel_Y(dCornerSizeY_Um); |
| | | double dCornerSizeX_Um = (double)pSideParam->m_nTopCornerSizeX_um; |
| | | int nCornerSizeX_Pixel = (int)GetUmToPixel_X(dCornerSizeX_Um); |
| | | |
| | | // 6. Find Conner Cut : |
| | | if(nCornerSizeX_Pixel != 0 && nCornerSizeY_Pixel != 0) |
| | | if (nCornerSizeX_Pixel != 0 && nCornerSizeY_Pixel != 0) |
| | | { |
| | | BOOL bFind = FALSE; |
| | | double dAddDistance = 0.0; |
| | | |
| | | int nSearchRange = 8; |
| | | |
| | | int nSearchRangeX = (int) ((double)nCornerSizeX_Pixel * 0.10); // 10%俊辑 茫澜.. |
| | | int nSearchRangeY = (int) ((double)nCornerSizeY_Pixel * 0.10); // 10%俊辑 茫澜.. |
| | | int nSearchRangeX = (int)((double)nCornerSizeX_Pixel * 0.10); // 10%에서 찾음.. |
| | | int nSearchRangeY = (int)((double)nCornerSizeY_Pixel * 0.10); // 10%에서 찾음.. |
| | | |
| | | nSearchRangeX = nSearchRangeY = 10; |
| | | |
| | | for(int i=ptConner[0].x ; i<pConnerEdgeOutLineImage->width; i++) |
| | | |
| | | for (int i = ptConner[0].x; i < pConnerEdgeOutLineImage->width; i++) |
| | | { |
| | | if(i < 0 || i >= pConnerEdgeOutLineImage->width) |
| | | if (i < 0 || i >= pConnerEdgeOutLineImage->width) |
| | | continue; |
| | | |
| | | if(nPos == 0) |
| | | if (nPos == 0) |
| | | { |
| | | //for(int j=0; j<nSearchRangeX; j++) |
| | | for(int j=-nSearchRangeX;j<nSearchRangeX;j++) |
| | | for (int j = -nSearchRangeX; j < nSearchRangeX; j++) |
| | | { |
| | | if((ptConner[0].y)+j < 0 || (ptConner[0].y)+j >= pConnerEdgeOutLineImage->height) |
| | | if ((ptConner[0].y) + j < 0 || (ptConner[0].y) + j >= pConnerEdgeOutLineImage->height) |
| | | continue; |
| | | |
| | | if(pConnerEdgeOutLineImage->imageData[i+(((ptConner[0].y)+j) * pConnerEdgeOutLineImage->widthStep)] != 0) |
| | | if (pConnerEdgeOutLineImage->imageData[i + (((ptConner[0].y) + j) * pConnerEdgeOutLineImage->widthStep)] != 0) |
| | | { |
| | | dAddDistance = (((double)j)*m_dPixelSizeY)/m_dPixelSizeX; |
| | | ptConner[1].x = i + (int) dAddDistance; |
| | | dAddDistance = (((double)j) * m_dPixelSizeY) / m_dPixelSizeX; |
| | | ptConner[1].x = i + (int)dAddDistance; |
| | | bFind = TRUE; |
| | | break; |
| | | } |
| | |
| | | else |
| | | { |
| | | //for(int j=0; j<nSearchRangeX; j++) |
| | | for(int j=-nSearchRangeX;j<nSearchRangeX;j++) |
| | | for (int j = -nSearchRangeX; j < nSearchRangeX; j++) |
| | | { |
| | | if((ptConner[0].y)-j < 0 || (ptConner[0].y)-j >= pConnerEdgeOutLineImage->height) |
| | | if ((ptConner[0].y) - j < 0 || (ptConner[0].y) - j >= pConnerEdgeOutLineImage->height) |
| | | continue; |
| | | |
| | | if(pConnerEdgeOutLineImage->imageData[i+(((ptConner[0].y)-j) * pConnerEdgeOutLineImage->widthStep)] != 0) |
| | | if (pConnerEdgeOutLineImage->imageData[i + (((ptConner[0].y) - j) * pConnerEdgeOutLineImage->widthStep)] != 0) |
| | | { |
| | | dAddDistance = (((double)j)*m_dPixelSizeY)/m_dPixelSizeX; |
| | | ptConner[1].x = i + (int) dAddDistance; |
| | | dAddDistance = (((double)j) * m_dPixelSizeY) / m_dPixelSizeX; |
| | | ptConner[1].x = i + (int)dAddDistance; |
| | | bFind = TRUE; |
| | | break; |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | if(bFind) |
| | | if (bFind) |
| | | break; |
| | | } |
| | | |
| | | bFind = FALSE; |
| | | |
| | | if(nPos == 0) |
| | | if (nPos == 0) |
| | | { |
| | | for(int i=ptConner[0].y ; i<pConnerEdgeOutLineImage->height; i++) |
| | | for (int i = ptConner[0].y; i < pConnerEdgeOutLineImage->height; i++) |
| | | { |
| | | if(i < 0 || i >= pConnerEdgeOutLineImage->height) |
| | | if (i < 0 || i >= pConnerEdgeOutLineImage->height) |
| | | continue; |
| | | |
| | | //for(int j=0; j<nSearchRangeY; j++) |
| | | for(int j=-nSearchRangeY;j<nSearchRangeY;j++) |
| | | for (int j = -nSearchRangeY; j < nSearchRangeY; j++) |
| | | { |
| | | if(ptConner[0].x+j < 0 || ptConner[0].x+j >= pConnerEdgeOutLineImage->widthStep) |
| | | if (ptConner[0].x + j < 0 || ptConner[0].x + j >= pConnerEdgeOutLineImage->widthStep) |
| | | continue; |
| | | |
| | | if(pConnerEdgeOutLineImage->imageData[ptConner[0].x+j+(i * pConnerEdgeOutLineImage->widthStep)] != 0) |
| | | if (pConnerEdgeOutLineImage->imageData[ptConner[0].x + j + (i * pConnerEdgeOutLineImage->widthStep)] != 0) |
| | | { |
| | | dAddDistance = (((double)j)*m_dPixelSizeX)/m_dPixelSizeY; |
| | | ptConner[2].y = i + (int) dAddDistance; |
| | | dAddDistance = (((double)j) * m_dPixelSizeX) / m_dPixelSizeY; |
| | | ptConner[2].y = i + (int)dAddDistance; |
| | | bFind = TRUE; |
| | | break; |
| | | } |
| | | } |
| | | |
| | | if(bFind) |
| | | if (bFind) |
| | | break; |
| | | } |
| | | } |
| | | else |
| | | { |
| | | for(int i=ptConner[0].y ; 0 <= i; i--) |
| | | for (int i = ptConner[0].y; 0 <= i; i--) |
| | | { |
| | | if(i < 0 || i >= pConnerEdgeOutLineImage->height) |
| | | if (i < 0 || i >= pConnerEdgeOutLineImage->height) |
| | | continue; |
| | | |
| | | //for(int j=0; j<nSearchRangeY; j++) |
| | | for(int j=-nSearchRangeY;j<nSearchRangeY;j++) |
| | | for (int j = -nSearchRangeY; j < nSearchRangeY; j++) |
| | | { |
| | | if(ptConner[0].x+j < 0 || ptConner[0].x+j >= pConnerEdgeOutLineImage->widthStep) |
| | | if (ptConner[0].x + j < 0 || ptConner[0].x + j >= pConnerEdgeOutLineImage->widthStep) |
| | | continue; |
| | | |
| | | if(pConnerEdgeOutLineImage->imageData[ptConner[0].x+j+(i * pConnerEdgeOutLineImage->widthStep)] != 0) |
| | | if (pConnerEdgeOutLineImage->imageData[ptConner[0].x + j + (i * pConnerEdgeOutLineImage->widthStep)] != 0) |
| | | { |
| | | dAddDistance = (((double)j)*m_dPixelSizeX)/m_dPixelSizeY; |
| | | ptConner[2].y = i - (int) dAddDistance; |
| | | dAddDistance = (((double)j) * m_dPixelSizeX) / m_dPixelSizeY; |
| | | ptConner[2].y = i - (int)dAddDistance; |
| | | bFind = TRUE; |
| | | break; |
| | | } |
| | | } |
| | | |
| | | if(bFind) |
| | | if (bFind) |
| | | break; |
| | | } |
| | | } |
| | | } |
| | | |
| | | if(nPos == 0) |
| | | { |
| | | pSideData->m_rtTopCornerResult[0].left = rtConnerRoi.left; |
| | | pSideData->m_rtTopCornerResult[0].top = rtConnerRoi.top; |
| | | pSideData->m_rtTopCornerResult[0].right = rtConnerRoi.right; |
| | | pSideData->m_rtTopCornerResult[0].bottom = rtConnerRoi.bottom; |
| | | } |
| | | |
| | | if(nPos == 0) |
| | | if (nPos == 0) |
| | | { |
| | | pSideData->m_rtTopCornerResult[0].left = rtConnerRoi.left; |
| | | pSideData->m_rtTopCornerResult[0].top = rtConnerRoi.top; |
| | | pSideData->m_rtTopCornerResult[0].right = rtConnerRoi.right; |
| | | pSideData->m_rtTopCornerResult[0].bottom = rtConnerRoi.bottom; |
| | | |
| | | if (nPos == 0) |
| | | { |
| | | pSideData->m_rtTopCornerResult[1].left = ptConner[0].x + rtConnerRoi.left; |
| | | pSideData->m_rtTopCornerResult[1].top = ptConner[0].y + rtConnerRoi.top; |
| | | pSideData->m_rtTopCornerResult[1].right = ptConner[1].x + rtConnerRoi.left; |
| | | pSideData->m_rtTopCornerResult[1].bottom = ptConner[2].y + rtConnerRoi.top; |
| | | pSideData->m_rtTopCornerResult[1].left = ptConner[0].x + rtConnerRoi.left; |
| | | pSideData->m_rtTopCornerResult[1].top = ptConner[0].y + rtConnerRoi.top; |
| | | pSideData->m_rtTopCornerResult[1].right = ptConner[1].x + rtConnerRoi.left; |
| | | pSideData->m_rtTopCornerResult[1].bottom = ptConner[2].y + rtConnerRoi.top; |
| | | } |
| | | else |
| | | { |
| | | pSideData->m_rtTopCornerResult[1].left = ptConner[0].x + rtConnerRoi.left; |
| | | pSideData->m_rtTopCornerResult[1].top = ptConner[2].y + rtConnerRoi.top; |
| | | pSideData->m_rtTopCornerResult[1].right = ptConner[1].x + rtConnerRoi.left; |
| | | pSideData->m_rtTopCornerResult[1].bottom = ptConner[0].y + rtConnerRoi.top; |
| | | } |
| | | pSideData->m_rtTopCornerResult[1].left = ptConner[0].x + rtConnerRoi.left; |
| | | pSideData->m_rtTopCornerResult[1].top = ptConner[2].y + rtConnerRoi.top; |
| | | pSideData->m_rtTopCornerResult[1].right = ptConner[1].x + rtConnerRoi.left; |
| | | pSideData->m_rtTopCornerResult[1].bottom = ptConner[0].y + rtConnerRoi.top; |
| | | } |
| | | |
| | | pSideData->m_nTopCornerWidth = (int)(abs(pSideData->m_rtTopCornerResult[1].right - pSideData->m_rtTopCornerResult[1].left) * m_dPixelSizeX); |
| | | pSideData->m_nTopCornerHeight = (int)(abs(pSideData->m_rtTopCornerResult[1].bottom - pSideData->m_rtTopCornerResult[1].top) * m_dPixelSizeY); |
| | | pSideData->m_nTopCornerWidth = (int)(abs(pSideData->m_rtTopCornerResult[1].right - pSideData->m_rtTopCornerResult[1].left) * m_dPixelSizeX); |
| | | pSideData->m_nTopCornerHeight = (int)(abs(pSideData->m_rtTopCornerResult[1].bottom - pSideData->m_rtTopCornerResult[1].top) * m_dPixelSizeY); |
| | | pSideData->m_bTopCorner_Measure = TRUE; |
| | | } |
| | | else |
| | | { |
| | | pSideData->m_rtBottomCornerResult[0].left = rtConnerRoi.left; |
| | | pSideData->m_rtBottomCornerResult[0].top = rtConnerRoi.top; |
| | | pSideData->m_rtBottomCornerResult[0].right = rtConnerRoi.right; |
| | | pSideData->m_rtBottomCornerResult[0].bottom = rtConnerRoi.bottom; |
| | | pSideData->m_rtBottomCornerResult[0].left = rtConnerRoi.left; |
| | | pSideData->m_rtBottomCornerResult[0].top = rtConnerRoi.top; |
| | | pSideData->m_rtBottomCornerResult[0].right = rtConnerRoi.right; |
| | | pSideData->m_rtBottomCornerResult[0].bottom = rtConnerRoi.bottom; |
| | | |
| | | if(nPos == 0) |
| | | if (nPos == 0) |
| | | { |
| | | pSideData->m_rtBottomCornerResult[1].left = ptConner[0].x + rtConnerRoi.left; |
| | | pSideData->m_rtBottomCornerResult[1].top = ptConner[0].y + rtConnerRoi.top; |
| | | pSideData->m_rtBottomCornerResult[1].right = ptConner[1].x + rtConnerRoi.left; |
| | | pSideData->m_rtBottomCornerResult[1].bottom = ptConner[2].y + rtConnerRoi.top; |
| | | pSideData->m_rtBottomCornerResult[1].left = ptConner[0].x + rtConnerRoi.left; |
| | | pSideData->m_rtBottomCornerResult[1].top = ptConner[0].y + rtConnerRoi.top; |
| | | pSideData->m_rtBottomCornerResult[1].right = ptConner[1].x + rtConnerRoi.left; |
| | | pSideData->m_rtBottomCornerResult[1].bottom = ptConner[2].y + rtConnerRoi.top; |
| | | } |
| | | else |
| | | { |
| | | pSideData->m_rtBottomCornerResult[1].left = ptConner[0].x + rtConnerRoi.left; |
| | | pSideData->m_rtBottomCornerResult[1].top = ptConner[2].y + rtConnerRoi.top; |
| | | pSideData->m_rtBottomCornerResult[1].right = ptConner[1].x + rtConnerRoi.left; |
| | | pSideData->m_rtBottomCornerResult[1].bottom = ptConner[0].y + rtConnerRoi.top; |
| | | } |
| | | pSideData->m_rtBottomCornerResult[1].left = ptConner[0].x + rtConnerRoi.left; |
| | | pSideData->m_rtBottomCornerResult[1].top = ptConner[2].y + rtConnerRoi.top; |
| | | pSideData->m_rtBottomCornerResult[1].right = ptConner[1].x + rtConnerRoi.left; |
| | | pSideData->m_rtBottomCornerResult[1].bottom = ptConner[0].y + rtConnerRoi.top; |
| | | } |
| | | |
| | | pSideData->m_nBottomCornerWidth = (int)(abs(pSideData->m_rtBottomCornerResult[1].right - pSideData->m_rtBottomCornerResult[1].left) * m_dPixelSizeX); |
| | | pSideData->m_nBottomCornerHeight = (int)(abs(pSideData->m_rtBottomCornerResult[1].bottom - pSideData->m_rtBottomCornerResult[1].top) * m_dPixelSizeY); |
| | | pSideData->m_nBottomCornerWidth = (int)(abs(pSideData->m_rtBottomCornerResult[1].right - pSideData->m_rtBottomCornerResult[1].left) * m_dPixelSizeX); |
| | | pSideData->m_nBottomCornerHeight = (int)(abs(pSideData->m_rtBottomCornerResult[1].bottom - pSideData->m_rtBottomCornerResult[1].top) * m_dPixelSizeY); |
| | | pSideData->m_bBotCorner_Measure = TRUE; |
| | | } |
| | | |
| | |
| | | cvReleaseImage(&pConnerEdgeOutLineImage); |
| | | |
| | | vecProjectionX.clear(); |
| | | vecProjectionY.clear(); |
| | | vecProjectionY.clear(); |
| | | |
| | | g_pLog->DisplayMessage(_T("%s Corner pos %d End, frame %d - %d,%d,%d,%d"),g_SideName[(int) emDim],nPos,stFrame.nFrameIdx,rtConnerRoi.left,rtConnerRoi.top,rtConnerRoi.right,rtConnerRoi.bottom); |
| | | g_pLog->DisplayMessage(_T("%s Corner pos %d End, frame %d - %d,%d,%d,%d"), g_SideName[(int)emDim], nPos, stFrame.nFrameIdx, rtConnerRoi.left, rtConnerRoi.top, rtConnerRoi.right, rtConnerRoi.bottom); |
| | | |
| | | return TRUE; |
| | | } |
| | | |
| | | BOOL CInspectCamera::Measure_TopCorner_RCut(int iThread,DimensionDir emDim, stFrameIndex stFrame) |
| | | BOOL CInspectCamera::Measure_TopCorner_RCut(int iThread, DimensionDir emDim, stFrameIndex stFrame) |
| | | { |
| | | if(m_pGlassData == NULL || m_pRecipe == NULL) |
| | | if (m_pGlassData == NULL || m_pRecipe == NULL) |
| | | return FALSE; |
| | | |
| | | CSide_Data* pSideData = m_pGlassData->GetSideData(emDim); |
| | | CSIDE_PARM* pSideParam = &m_pRecipe->m_SideParam[(int) emDim]; |
| | | CSide_Data* pSideData = m_pGlassData->GetSideData(emDim); |
| | | CSIDE_PARM* pSideParam = &m_pRecipe->m_SideParam[(int)emDim]; |
| | | |
| | | if(pSideData == NULL || pSideParam == NULL) |
| | | if (pSideData == NULL || pSideParam == NULL) |
| | | return FALSE; |
| | | |
| | | // R Corner 螟沥 |
| | | // R Corner 측정 |
| | | |
| | | return TRUE; |
| | | } |
| | | |
| | | BOOL CInspectCamera::Measure_BotCorner(int iThread,DimensionDir emDim, stFrameIndex stFrame) |
| | | BOOL CInspectCamera::Measure_BotCorner(int iThread, DimensionDir emDim, stFrameIndex stFrame) |
| | | { |
| | | if(m_pGlassData == NULL || m_pRecipe == NULL) |
| | | if (m_pGlassData == NULL || m_pRecipe == NULL) |
| | | return FALSE; |
| | | |
| | | CSide_Data* pSideData = m_pGlassData->GetSideData(emDim); |
| | | CSIDE_PARM* pSideParam = &m_pRecipe->m_SideParam[(int) emDim]; |
| | | CSide_Data* pSideData = m_pGlassData->GetSideData(emDim); |
| | | CSIDE_PARM* pSideParam = &m_pRecipe->m_SideParam[(int)emDim]; |
| | | |
| | | if(pSideData == NULL || pSideParam == NULL) |
| | | if (pSideData == NULL || pSideParam == NULL) |
| | | return FALSE; |
| | | |
| | | if(pSideParam->m_bBottomCornerMeasureSize == FALSE) |
| | | if (pSideParam->m_bBottomCornerMeasureSize == FALSE) |
| | | return FALSE; |
| | | |
| | | if (pSideData->m_bBotCorner_Find == FALSE) |
| | |
| | | |
| | | int nBotCornerType = pSideData->m_nBotCornerShape; |
| | | |
| | | if(nBotCornerType == (int) 1) return Measure_BotCorner_CCut(iThread, emDim, stFrame); |
| | | else if(nBotCornerType == (int) 2) return Measure_BotCorner_RCut(iThread, emDim, stFrame); |
| | | if (nBotCornerType == (int)1) return Measure_BotCorner_CCut(iThread, emDim, stFrame); |
| | | else if (nBotCornerType == (int)2) return Measure_BotCorner_RCut(iThread, emDim, stFrame); |
| | | else pSideData->m_bBotCorner_Measure = TRUE; |
| | | |
| | | return TRUE; |
| | | } |
| | | |
| | | BOOL CInspectCamera::Measure_BotCorner_CCut(int iThread,DimensionDir emDim, stFrameIndex stFrame) |
| | | BOOL CInspectCamera::Measure_BotCorner_CCut(int iThread, DimensionDir emDim, stFrameIndex stFrame) |
| | | { |
| | | if(m_pGlassData == NULL || m_pRecipe == NULL) |
| | | if (m_pGlassData == NULL || m_pRecipe == NULL) |
| | | return FALSE; |
| | | |
| | | CSide_Data* pSideData = m_pGlassData->GetSideData(emDim); |
| | | CSIDE_PARM* pSideParam = &m_pRecipe->m_SideParam[(int) emDim]; |
| | | CSide_Data* pSideData = m_pGlassData->GetSideData(emDim); |
| | | CSIDE_PARM* pSideParam = &m_pRecipe->m_SideParam[(int)emDim]; |
| | | |
| | | if(pSideData == NULL || pSideParam == NULL) |
| | | if (pSideData == NULL || pSideParam == NULL) |
| | | return FALSE; |
| | | |
| | | CRect rtBottomCornerArea = pSideData->m_rtBotCornerArea; |
| | | |
| | | rtBottomCornerArea.InflateRect(50,50); |
| | | rtBottomCornerArea.InflateRect(50, 50); |
| | | |
| | | int iCornerFrame = rtBottomCornerArea.bottom/m_nFrameHeight; |
| | | int iCornerFrame = rtBottomCornerArea.bottom / m_nFrameHeight; |
| | | |
| | | if(iCornerFrame > stFrame.nFrameIdx) |
| | | if (iCornerFrame > stFrame.nFrameIdx) |
| | | return FALSE; |
| | | |
| | | // Corner 八荤 父甸扁.. |
| | | if(FindCorner(iThread,emDim,stFrame,1,rtBottomCornerArea) == TRUE) |
| | | // Corner 검사 만들기.. |
| | | if (FindCorner(iThread, emDim, stFrame, 1, rtBottomCornerArea) == TRUE) |
| | | { |
| | | double dXSizeStd_um = pSideParam->m_nBottomCorner_Measure_Judge_Std_um_X; |
| | | double dXSizeMin_um = pSideParam->m_nBottomCorner_Measure_Judge_Min_um_X; |
| | |
| | | double dYSizeMax_um = pSideParam->m_nBottomCorner_Measure_Judge_Max_um_Y; |
| | | int nOpt = pSideParam->m_nBottomCorner_Measure_Judge_OR_AND; |
| | | |
| | | if(nOpt == 0) |
| | | if (nOpt == 0) |
| | | return FALSE; |
| | | |
| | | double dResultWidth_um = pSideData->m_nBottomCornerWidth; |
| | | double dResultHeight_um = pSideData->m_nBottomCornerHeight; |
| | | |
| | | pSideData->m_bBottomMeasureResult = TRUE; |
| | | if(nOpt == 1) // or |
| | | if (nOpt == 1) // or |
| | | { |
| | | if( (dResultWidth_um < dXSizeStd_um-dXSizeMin_um || dResultWidth_um > dXSizeStd_um+dXSizeMax_um) || (dResultHeight_um < dYSizeStd_um-dYSizeMin_um || dResultHeight_um > dYSizeStd_um+dYSizeMax_um)) |
| | | if ((dResultWidth_um < dXSizeStd_um - dXSizeMin_um || dResultWidth_um > dXSizeStd_um + dXSizeMax_um) || (dResultHeight_um < dYSizeStd_um - dYSizeMin_um || dResultHeight_um > dYSizeStd_um + dYSizeMax_um)) |
| | | { |
| | | pSideData->m_bBottomMeasureResult = FALSE; // NG |
| | | } |
| | | } |
| | | else // and |
| | | { |
| | | if( (dResultWidth_um < dXSizeStd_um-dXSizeMin_um || dResultWidth_um > dXSizeStd_um+dXSizeMax_um) && (dResultHeight_um < dYSizeStd_um-dYSizeMin_um || dResultHeight_um > dYSizeStd_um+dYSizeMax_um)) |
| | | if ((dResultWidth_um < dXSizeStd_um - dXSizeMin_um || dResultWidth_um > dXSizeStd_um + dXSizeMax_um) && (dResultHeight_um < dYSizeStd_um - dYSizeMin_um || dResultHeight_um > dYSizeStd_um + dYSizeMax_um)) |
| | | { |
| | | pSideData->m_bBottomMeasureResult = FALSE; // NG |
| | | } |
| | | } |
| | | |
| | | if(pSideData->m_bBottomMeasureResult == FALSE) |
| | | if (pSideData->m_bBottomMeasureResult == FALSE) |
| | | { |
| | | // Make Defect |
| | | CDefect_Info measureDefect; |
| | |
| | | measureDefect.m_nCamID = m_iCamera; |
| | | measureDefect.m_nScanIdx = stFrame.nScanIdx; |
| | | measureDefect.m_nGlassStartLine = pSideData->m_nGlassStartLine; |
| | | measureDefect.m_nSideIdx = (int) emDim; |
| | | measureDefect.m_nSideIdx = (int)emDim; |
| | | measureDefect.m_DefectLoc = DefectLoc_Measure_Corner; |
| | | measureDefect.m_ptDefectPos_pxl = pSideData->m_rtTopCornerResult[1].CenterPoint(); |
| | | measureDefect.m_rtDefectPos_pxl = CRect(measureDefect.m_ptDefectPos_pxl.x - 16, measureDefect.m_ptDefectPos_pxl.y - 16, measureDefect.m_ptDefectPos_pxl.x + 16, measureDefect.m_ptDefectPos_pxl.y + 16); |
| | | |
| | | g_pLog->DisplayMessage(_T("Measure Bottom Corner NG Start %s : %d,%d"),g_SideName[(int) emDim],measureDefect.m_ptDefectPos_pxl.x,measureDefect.m_ptDefectPos_pxl.y); |
| | | g_pLog->DisplayMessage(_T("Measure Bottom Corner NG Start %s : %d,%d"), g_SideName[(int)emDim], measureDefect.m_ptDefectPos_pxl.x, measureDefect.m_ptDefectPos_pxl.y); |
| | | |
| | | m_pDefectControl->ExtractDefect_Measure(emDim, m_iCamera, stFrame.nScanIdx, measureDefect, dResultWidth_um, dResultHeight_um); |
| | | |
| | | g_pLog->DisplayMessage(_T("Measure Bottom Corner NG End %s : %d,%d"),g_SideName[(int) emDim],measureDefect.m_ptDefectPos_pxl.x,measureDefect.m_ptDefectPos_pxl.y); |
| | | g_pLog->DisplayMessage(_T("Measure Bottom Corner NG End %s : %d,%d"), g_SideName[(int)emDim], measureDefect.m_ptDefectPos_pxl.x, measureDefect.m_ptDefectPos_pxl.y); |
| | | } |
| | | } |
| | | |
| | | return TRUE; |
| | | } |
| | | |
| | | BOOL CInspectCamera::Measure_BotCorner_RCut(int iThread,DimensionDir emDim, stFrameIndex stFrame) |
| | | BOOL CInspectCamera::Measure_BotCorner_RCut(int iThread, DimensionDir emDim, stFrameIndex stFrame) |
| | | { |
| | | |
| | | return TRUE; |
| | | } |
| | | |
| | | BOOL CInspectCamera::UserDefect_Process(int iThread,DimensionDir emDim, stFrameIndex stFrame) |
| | | BOOL CInspectCamera::UserDefect_Process(int iThread, DimensionDir emDim, stFrameIndex stFrame) |
| | | { |
| | | if(m_pGlassData == NULL) |
| | | if (m_pGlassData == NULL) |
| | | return FALSE; |
| | | |
| | | CSide_Data* pSideData = m_pGlassData->GetSideData(emDim); |
| | | CSide_Data* pSideData = m_pGlassData->GetSideData(emDim); |
| | | |
| | | if(pSideData == NULL) |
| | | if (pSideData == NULL) |
| | | return FALSE; |
| | | |
| | | if(pSideData->m_bFindGlassEndLine == FALSE) // User Defect Processing篮 End Line 茫篮 Frame捞.. |
| | | if (pSideData->m_bFindGlassEndLine == FALSE) // User Defect Processing은 End Line 찾은 Frame이.. |
| | | return FALSE; |
| | | |
| | | if(m_pRecipe == NULL) |
| | | if (m_pRecipe == NULL) |
| | | return FALSE; |
| | | |
| | | if(m_pDefectControl == NULL) |
| | | if (m_pDefectControl == NULL) |
| | | return FALSE; |
| | | |
| | | std::vector<CDefect_Info> vecDefectCandidateList; |
| | | |
| | | int nUserDefectAreaCount = m_pRecipe->m_SideParam[(int) emDim].m_nUserDefectAreaCount; |
| | | int nUserDefectAreaCount = m_pRecipe->m_SideParam[(int)emDim].m_nUserDefectAreaCount; |
| | | |
| | | pSideData->m_nUserDefectAreaCount = nUserDefectAreaCount; |
| | | |
| | | for(int i=0; i<nUserDefectAreaCount; i++) |
| | | for (int i = 0; i < nUserDefectAreaCount; i++) |
| | | { |
| | | if(m_pRecipe->m_SideParam[(int) emDim].m_UserDefectPrm[i].m_bUseInspect == 0) |
| | | if (m_pRecipe->m_SideParam[(int)emDim].m_UserDefectPrm[i].m_bUseInspect == 0) |
| | | continue; |
| | | |
| | | CPoint ptSet_TopMark = m_pRecipe->m_SideParam[(int) emDim].m_UserDefectPrm[i].m_ptTopMarkPos; |
| | | CPoint ptSet_BotMark = m_pRecipe->m_SideParam[(int) emDim].m_UserDefectPrm[i].m_ptBotMarkPos; |
| | | CRect rtSet_Area = m_pRecipe->m_SideParam[(int) emDim].m_UserDefectPrm[i].m_rtUserDefectArea; |
| | | CPoint ptSet_TopMark = m_pRecipe->m_SideParam[(int)emDim].m_UserDefectPrm[i].m_ptTopMarkPos; |
| | | CPoint ptSet_BotMark = m_pRecipe->m_SideParam[(int)emDim].m_UserDefectPrm[i].m_ptBotMarkPos; |
| | | CRect rtSet_Area = m_pRecipe->m_SideParam[(int)emDim].m_UserDefectPrm[i].m_rtUserDefectArea; |
| | | |
| | | CRect rtRotateArea; |
| | | |
| | | if(GetAlignRotate(emDim, ptSet_TopMark, ptSet_BotMark, rtSet_Area, rtRotateArea) == FALSE) |
| | | if (GetAlignRotate(emDim, ptSet_TopMark, ptSet_BotMark, rtSet_Area, rtRotateArea) == FALSE) |
| | | continue; |
| | | |
| | | pSideData->m_rtUserDefectArea_pxl[i] = rtRotateArea; |
| | |
| | | return TRUE; |
| | | } |
| | | |
| | | BOOL CInspectCamera::InspectDefect_UserDefectProcess(int iThread,DimensionDir emDim, stFrameIndex stFrame, int nUserDefectIdx, CRect rtUserDefectArea, std::vector<CDefect_Info>* pDefectList) |
| | | BOOL CInspectCamera::InspectDefect_UserDefectProcess(int iThread, DimensionDir emDim, stFrameIndex stFrame, int nUserDefectIdx, CRect rtUserDefectArea, std::vector<CDefect_Info>* pDefectList) |
| | | { |
| | | if (rtUserDefectArea.IsRectEmpty() == TRUE || m_pGlassData == NULL) |
| | | return FALSE; |
| | | |
| | | DefectLocation defectLoc = DefectLoc_UserDefect; |
| | | |
| | | if(m_pRecipe->m_SideParam[(int) emDim].m_UserDefectPrm[nUserDefectIdx].m_bUseInspect == FALSE) |
| | | if (m_pRecipe->m_SideParam[(int)emDim].m_UserDefectPrm[nUserDefectIdx].m_bUseInspect == FALSE) |
| | | return TRUE; |
| | | |
| | | // 0. Parameter Initialize.. |
| | | CString strDefectType = _T("Unknown"); |
| | | int nMethod = 0; |
| | | int nThreshold_Low = 0; |
| | | int nThreshold_High = 0; |
| | | int nPitch = 0; |
| | | int nPitch_Threshold = 0; |
| | | int nMinSize = 0; |
| | | int nJudge_Size_Min_X_um = 0; |
| | | int nJudge_Size_Min_Y_um = 0; |
| | | int nJudge_Size_Min_OR_AND = 0; // 0 : No Use, 1 : OR, 2 : AND |
| | | CString strDefectType = _T("Unknown"); |
| | | int nMethod = 0; |
| | | int nThreshold_Low = 0; |
| | | int nThreshold_High = 0; |
| | | int nPitch = 0; |
| | | int nPitch_Threshold = 0; |
| | | int nMinSize = 0; |
| | | int nJudge_Size_Min_X_um = 0; |
| | | int nJudge_Size_Min_Y_um = 0; |
| | | int nJudge_Size_Min_OR_AND = 0; // 0 : No Use, 1 : OR, 2 : AND |
| | | |
| | | nMethod = m_pRecipe->m_SideParam[(int) emDim].m_UserDefectPrm[nUserDefectIdx].m_nInspect_Method; |
| | | nThreshold_Low = m_pRecipe->m_SideParam[(int) emDim].m_UserDefectPrm[nUserDefectIdx].m_nMin_Threshold; |
| | | nThreshold_High = m_pRecipe->m_SideParam[(int) emDim].m_UserDefectPrm[nUserDefectIdx].m_nMax_Threshold; |
| | | nPitch = m_pRecipe->m_SideParam[(int) emDim].m_UserDefectPrm[nUserDefectIdx].m_nDiff_Pitch; |
| | | nPitch_Threshold = m_pRecipe->m_SideParam[(int) emDim].m_UserDefectPrm[nUserDefectIdx].m_nDiff_Threshold; |
| | | nMinSize = m_pRecipe->m_SideParam[(int) emDim].m_UserDefectPrm[nUserDefectIdx].m_nMinSize_Filter_pxl; |
| | | nJudge_Size_Min_X_um = m_pRecipe->m_SideParam[(int) emDim].m_UserDefectPrm[nUserDefectIdx].m_nJudge_Size_Min_X_um; |
| | | nJudge_Size_Min_Y_um = m_pRecipe->m_SideParam[(int) emDim].m_UserDefectPrm[nUserDefectIdx].m_nJudge_Size_Min_Y_um; |
| | | nJudge_Size_Min_OR_AND = m_pRecipe->m_SideParam[(int) emDim].m_UserDefectPrm[nUserDefectIdx].m_nJudge_Size_Min_OR_AND; |
| | | nMethod = m_pRecipe->m_SideParam[(int)emDim].m_UserDefectPrm[nUserDefectIdx].m_nInspect_Method; |
| | | nThreshold_Low = m_pRecipe->m_SideParam[(int)emDim].m_UserDefectPrm[nUserDefectIdx].m_nMin_Threshold; |
| | | nThreshold_High = m_pRecipe->m_SideParam[(int)emDim].m_UserDefectPrm[nUserDefectIdx].m_nMax_Threshold; |
| | | nPitch = m_pRecipe->m_SideParam[(int)emDim].m_UserDefectPrm[nUserDefectIdx].m_nDiff_Pitch; |
| | | nPitch_Threshold = m_pRecipe->m_SideParam[(int)emDim].m_UserDefectPrm[nUserDefectIdx].m_nDiff_Threshold; |
| | | nMinSize = m_pRecipe->m_SideParam[(int)emDim].m_UserDefectPrm[nUserDefectIdx].m_nMinSize_Filter_pxl; |
| | | nJudge_Size_Min_X_um = m_pRecipe->m_SideParam[(int)emDim].m_UserDefectPrm[nUserDefectIdx].m_nJudge_Size_Min_X_um; |
| | | nJudge_Size_Min_Y_um = m_pRecipe->m_SideParam[(int)emDim].m_UserDefectPrm[nUserDefectIdx].m_nJudge_Size_Min_Y_um; |
| | | nJudge_Size_Min_OR_AND = m_pRecipe->m_SideParam[(int)emDim].m_UserDefectPrm[nUserDefectIdx].m_nJudge_Size_Min_OR_AND; |
| | | |
| | | CSISBuffer frameBuffer(m_pGrabber->GetFrameHeaderLine(stFrame.nScanIdx, rtUserDefectArea.top), m_nFrameWidth, m_nFrameHeight); |
| | | if(frameBuffer.IsValidBuffer() == FALSE) |
| | | if (frameBuffer.IsValidBuffer() == FALSE) |
| | | return FALSE; |
| | | |
| | | // 1. Inspect ROI |
| | | COwnerBuffer pDefectProcessImage(rtUserDefectArea.Width(), rtUserDefectArea.Height()); |
| | | |
| | | for (int i = 0; i < rtUserDefectArea.Height(); i++) |
| | | memcpy(pDefectProcessImage.GetDataAddress(0,i), frameBuffer.GetDataAddress(rtUserDefectArea.left, i), rtUserDefectArea.Width()); |
| | | memcpy(pDefectProcessImage.GetDataAddress(0, i), frameBuffer.GetDataAddress(rtUserDefectArea.left, i), rtUserDefectArea.Width()); |
| | | |
| | | // 2. Inspect Algorithm |
| | | COwnerBuffer pBinImage; |
| | |
| | | return TRUE; |
| | | } |
| | | |
| | | BOOL CInspectCamera::ExceptionArea_Process(int iThread,DimensionDir emDim, stFrameIndex stFrame) |
| | | BOOL CInspectCamera::ExceptionArea_Process(int iThread, DimensionDir emDim, stFrameIndex stFrame) |
| | | { |
| | | if(m_pGlassData == NULL) |
| | | if (m_pGlassData == NULL) |
| | | return FALSE; |
| | | |
| | | CSide_Data* pSideData = m_pGlassData->GetSideData(emDim); |
| | | CSide_Data* pSideData = m_pGlassData->GetSideData(emDim); |
| | | |
| | | if(pSideData == NULL) |
| | | if (pSideData == NULL) |
| | | return FALSE; |
| | | |
| | | if(pSideData->m_bFindGlassEndLine == FALSE) // Exception Area Processing篮 End Line 茫篮 Frame捞.. |
| | | if (pSideData->m_bFindGlassEndLine == FALSE) // Exception Area Processing은 End Line 찾은 Frame이.. |
| | | return FALSE; |
| | | |
| | | if(m_pRecipe == NULL) |
| | | if (m_pRecipe == NULL) |
| | | return FALSE; |
| | | |
| | | if(m_pDefectControl == NULL) |
| | | if (m_pDefectControl == NULL) |
| | | return FALSE; |
| | | |
| | | int nExceptionCount = m_pRecipe->m_SideParam[(int) emDim].m_nExptionCount; |
| | | int nExceptionCount = m_pRecipe->m_SideParam[(int)emDim].m_nExptionCount; |
| | | |
| | | pSideData->m_nExceptionAreaCount = nExceptionCount; |
| | | |
| | | for(int i=0; i<nExceptionCount; i++) |
| | | for (int i = 0; i < nExceptionCount; i++) |
| | | { |
| | | if(m_pRecipe->m_SideParam[(int) emDim].m_ExpAreaPrm[i].m_nFilterType == 0) |
| | | if (m_pRecipe->m_SideParam[(int)emDim].m_ExpAreaPrm[i].m_nFilterType == 0) |
| | | continue; |
| | | |
| | | CPoint ptSet_TopMark = m_pRecipe->m_SideParam[(int) emDim].m_ExpAreaPrm[i].m_ptTopMarkPos; |
| | | CPoint ptSet_BotMark = m_pRecipe->m_SideParam[(int) emDim].m_ExpAreaPrm[i].m_ptBotMarkPos; |
| | | CRect rtSet_Area = m_pRecipe->m_SideParam[(int) emDim].m_ExpAreaPrm[i].m_rtExceptionArea; |
| | | CPoint ptSet_TopMark = m_pRecipe->m_SideParam[(int)emDim].m_ExpAreaPrm[i].m_ptTopMarkPos; |
| | | CPoint ptSet_BotMark = m_pRecipe->m_SideParam[(int)emDim].m_ExpAreaPrm[i].m_ptBotMarkPos; |
| | | CRect rtSet_Area = m_pRecipe->m_SideParam[(int)emDim].m_ExpAreaPrm[i].m_rtExceptionArea; |
| | | |
| | | CRect rtRotateArea; |
| | | |
| | | if(GetAlignRotate(emDim, ptSet_TopMark, ptSet_BotMark, rtSet_Area, rtRotateArea) == FALSE) |
| | | if (GetAlignRotate(emDim, ptSet_TopMark, ptSet_BotMark, rtSet_Area, rtRotateArea) == FALSE) |
| | | continue; |
| | | |
| | | pSideData->m_rtExceptionArea_pxl[i] = rtRotateArea; |
| | | |
| | | int nDefectCount = m_pDefectControl->GetDefectCount(); |
| | | |
| | | for(int nDefectIdx=0; nDefectIdx<nDefectCount; nDefectIdx++) |
| | | for (int nDefectIdx = 0; nDefectIdx < nDefectCount; nDefectIdx++) |
| | | { |
| | | CDefect* pDefect = m_pDefectControl->GetDefect(nDefectIdx); |
| | | |
| | | if(pDefect == NULL) |
| | | if (pDefect == NULL) |
| | | continue; |
| | | |
| | | CRect rtDefectArea = pDefect->m_DefectInfo.m_rtDefectPos_pxl; |
| | |
| | | CRect rtIntersect; |
| | | rtIntersect.IntersectRect(rtRotateArea, rtDefectArea); |
| | | |
| | | if(rtIntersect == rtDefectArea) |
| | | if (rtIntersect == rtDefectArea) |
| | | pDefect->m_nExceptionArea = 2; |
| | | else if(0 < rtIntersect.Width() || 0 < rtIntersect.Height()) |
| | | else if (0 < rtIntersect.Width() || 0 < rtIntersect.Height()) |
| | | pDefect->m_nExceptionArea = 1; |
| | | else |
| | | continue; |
| | | |
| | | int nFilterType = m_pRecipe->m_SideParam[(int) emDim].m_ExpAreaPrm[i].m_nFilterType; |
| | | int nFilterType = m_pRecipe->m_SideParam[(int)emDim].m_ExpAreaPrm[i].m_nFilterType; |
| | | |
| | | if(nFilterType == 0) |
| | | if (nFilterType == 0) |
| | | continue; |
| | | else if(nFilterType == 1 && (pDefect->m_nExceptionArea == 1 || pDefect->m_nExceptionArea == 2)) |
| | | else if (nFilterType == 1 && (pDefect->m_nExceptionArea == 1 || pDefect->m_nExceptionArea == 2)) |
| | | pDefect->m_DefectInfo.m_DefectLoc = DefectLoc_Exception; |
| | | else if(nFilterType == 2 && pDefect->m_nExceptionArea == 2) |
| | | else if (nFilterType == 2 && pDefect->m_nExceptionArea == 2) |
| | | pDefect->m_DefectInfo.m_DefectLoc = DefectLoc_Exception; |
| | | } |
| | | } |
| | |
| | | return TRUE; |
| | | } |
| | | |
| | | void CInspectCamera::SaveGlassLineImage(int iScan,int nLine,int nXPos,DimensionDir emDim,CString strName) |
| | | void CInspectCamera::SaveGlassLineImage(int iScan, int nLine, int nXPos, DimensionDir emDim, CString strName) |
| | | { |
| | | int nImgWidth = 100; |
| | | int nImgHeight = 200; |
| | | |
| | | CvRect saveRect = cvRect(nXPos-nImgWidth,0,nImgWidth*2,nImgHeight*2); |
| | | int nImgHeight = 200; |
| | | |
| | | int iStartV = nLine-nImgHeight; |
| | | CvRect saveRect = cvRect(nXPos - nImgWidth, 0, nImgWidth * 2, nImgHeight * 2); |
| | | |
| | | if(iStartV < 0) |
| | | int iStartV = nLine - nImgHeight; |
| | | |
| | | if (iStartV < 0) |
| | | iStartV = 0; |
| | | |
| | | LPBYTE pImg = m_pGrabber->GetFrameHeaderLine(iScan,iStartV); |
| | | if(pImg == NULL) |
| | | LPBYTE pImg = m_pGrabber->GetFrameHeaderLine(iScan, iStartV); |
| | | if (pImg == NULL) |
| | | return; |
| | | |
| | | IplImage *IpImg = cvCreateImage(cvSize(saveRect.width,saveRect.height),8,1); |
| | | IplImage* IpImg = cvCreateImage(cvSize(saveRect.width, saveRect.height), 8, 1); |
| | | |
| | | cvZero(IpImg); |
| | | |
| | | int nFrameWidth,nFrameHeight; |
| | | int nFrameWidth, nFrameHeight; |
| | | |
| | | GetFrameSize(m_iCamera,iScan,nFrameWidth,nFrameHeight); |
| | | GetFrameSize(m_iCamera, iScan, nFrameWidth, nFrameHeight); |
| | | |
| | | for(int i=0; i< saveRect.height; i++) |
| | | { |
| | | memcpy(&IpImg->imageData[IpImg->widthStep*i], pImg+saveRect.x, sizeof(BYTE)*IpImg->width); |
| | | for (int i = 0; i < saveRect.height; i++) |
| | | { |
| | | memcpy(&IpImg->imageData[IpImg->widthStep * i], pImg + saveRect.x, sizeof(BYTE) * IpImg->width); |
| | | pImg += nFrameWidth; |
| | | } |
| | | |
| | | CString strFile; |
| | | strFile.Format(_T("%s\\IMG_MARK\\%s\\%s\\%s\\%s_%s.jpg"),PATH_INSPECTION_DATA,g_pBase->m_strLoadingDay,g_pBase->m_strHPanelID,g_pBase->m_strLoadingTime,PANEL_SIDE[emDim],strName); |
| | | strFile.Format(_T("%s\\IMG_MARK\\%s\\%s\\%s\\%s_%s.jpg"), PATH_INSPECTION_DATA, g_pBase->m_strLoadingDay, g_pBase->m_strHPanelID, g_pBase->m_strLoadingTime, PANEL_SIDE[emDim], strName); |
| | | |
| | | g_pStatus->CheckDirectory(strFile); |
| | | |
| | | cv::Point startPoint(0,saveRect.height/2); |
| | | cv::Point endPoint(saveRect.width,saveRect.height/2); |
| | | cv::Point startPoint(0, saveRect.height / 2); |
| | | cv::Point endPoint(saveRect.width, saveRect.height / 2); |
| | | |
| | | cvLine(IpImg, startPoint, endPoint, cvScalar(255, 0, 0), 1); |
| | | |
| | | USES_CONVERSION; |
| | | char str_filename[1024]; |
| | | sprintf_s(str_filename, "%s", W2A(strFile)); |
| | | cvSaveImage(str_filename,IpImg); |
| | | |
| | | cvSaveImage(str_filename, IpImg); |
| | | |
| | | cvReleaseImage(&IpImg); |
| | | } |
| | | |
| | | BOOL CInspectCamera::OnThreadEnd(int iThread, CInspectThread *pInspectThread) |
| | | BOOL CInspectCamera::OnThreadEnd(int iThread, CInspectThread* pInspectThread) |
| | | { |
| | | return TRUE; |
| | | } |
| | |
| | | } |
| | | |
| | | void CInspectCamera::ReleaseFullBuffer() |
| | | { |
| | | { |
| | | int i; |
| | | for(i=0;i<MAX_SCAN_COUNT;i++) |
| | | for (i = 0; i < MAX_SCAN_COUNT; i++) |
| | | { |
| | | m_FullImgBuffer[i].Reset(); |
| | | } |
| | | } |
| | | } |
| | | |
| | | void CInspectCamera::SetSimulation(BOOL bSimulation) |
| | | { |
| | | m_bSimulation = bSimulation; |
| | | |
| | | if(m_pGlassData == NULL) |
| | | if (m_pGlassData == NULL) |
| | | return; |
| | | |
| | | m_pGlassData->SetSimulation(bSimulation); |
| | | } |
| | | |
| | | void CInspectCamera::SetParameter(CGlassRecipe *pRecipe,CHardwareSettings *pHW) |
| | | void CInspectCamera::SetParameter(CGlassRecipe* pRecipe, CHardwareSettings* pHW) |
| | | { |
| | | g_pLog->DisplayMessage(_T("SetParameter Cam[%d] start"),m_iCamera); |
| | | g_pLog->DisplayMessage(_T("SetParameter Cam[%d] start"), m_iCamera); |
| | | |
| | | m_bExitThread = TRUE; |
| | | ZeroMemory(m_iThreadEnd,sizeof(m_iThreadEnd)); |
| | | ZeroMemory(m_bFindGlassStart,sizeof(m_bFindGlassStart)); |
| | | ZeroMemory(m_iSideLine,sizeof(m_iSideLine)); |
| | | |
| | | ZeroMemory(m_iThreadEnd, sizeof(m_iThreadEnd)); |
| | | ZeroMemory(m_bFindGlassStart, sizeof(m_bFindGlassStart)); |
| | | ZeroMemory(m_iSideLine, sizeof(m_iSideLine)); |
| | | |
| | | m_pRecipe = pRecipe; |
| | | m_pHardparm = pHW; |
| | | |
| | | if(m_pGrabber != NULL) |
| | | if (m_pGrabber != NULL) |
| | | { |
| | | m_pGrabber->ClearGrabIdx(); |
| | | //m_pGrabber->ClearBuffer(); |
| | | } |
| | | |
| | | if(m_pDefectControl != NULL) |
| | | } |
| | | |
| | | if (m_pDefectControl != NULL) |
| | | { |
| | | m_pDefectControl->SetHWRecipe(pHW); |
| | | m_pDefectControl->ResetDefectControl(); |
| | | } |
| | | |
| | | g_pLog->DisplayMessage(_T("SetParameter Cam[%d] end"),m_iCamera); |
| | | g_pLog->DisplayMessage(_T("SetParameter Cam[%d] end"), m_iCamera); |
| | | } |
| | | |
| | | void CInspectCamera::SetGlassData(CGlass_Data *pGlassData) |
| | | void CInspectCamera::SetGlassData(CGlass_Data* pGlassData) |
| | | { |
| | | m_pGlassData = pGlassData; |
| | | |
| | | if(m_pGrabber != NULL) |
| | | if (m_pGrabber != NULL) |
| | | { |
| | | for(int i=0;i<MAX_DIMENSION_COUNT;i++) |
| | | for (int i = 0; i < MAX_DIMENSION_COUNT; i++) |
| | | { |
| | | CSide_Data* pSideData = m_pGlassData->GetSideData((DimensionDir)i); |
| | | if(pSideData == NULL) |
| | | if (pSideData == NULL) |
| | | continue; |
| | | |
| | | pSideData->m_nPreGlassEndFrame = m_pGrabber->GetFrameBuffer()->GetFrameCount()-1; |
| | | pSideData->m_nPreGlassEndFrame = m_pGrabber->GetFrameBuffer()->GetFrameCount() - 1; |
| | | } |
| | | } |
| | | } |
| | | |
| | | void CInspectCamera::SetGrabber(CGrabberControl *pGrabber) |
| | | void CInspectCamera::SetGrabber(CGrabberControl* pGrabber) |
| | | { |
| | | m_pGrabber = pGrabber; |
| | | if(m_pDefectControl != NULL) |
| | | if (m_pDefectControl != NULL) |
| | | m_pDefectControl->SetGrabber(pGrabber); |
| | | } |
| | | |
| | | DimensionDir CInspectCamera::GetDimension(int iScan) |
| | | { |
| | | CCameraSettings *pCamera = m_pHardparm->GetCameraSettings(m_iCamera,iScan); |
| | | if(pCamera == NULL) |
| | | CCameraSettings* pCamera = m_pHardparm->GetCameraSettings(m_iCamera, iScan); |
| | | if (pCamera == NULL) |
| | | return DIMENSION_NONE; |
| | | |
| | | return pCamera->m_eDimension; |
| | |
| | | { |
| | | g_pLog->DisplayMessage(_T("Set Grab End")); |
| | | |
| | | CCameraSettings *pCamera = m_pHardparm->GetCameraSettings(m_iCamera,iScan); |
| | | |
| | | if(pCamera == NULL) |
| | | CCameraSettings* pCamera = m_pHardparm->GetCameraSettings(m_iCamera, iScan); |
| | | |
| | | if (pCamera == NULL) |
| | | { |
| | | g_pLog->DisplayMessage(_T("Camera Setting NULL")); |
| | | return; |
| | |
| | | |
| | | DimensionDir emDim = pCamera->m_eDimension; |
| | | CSide_Data* pSideData = m_pGlassData->GetSideData(emDim); |
| | | if(pSideData == NULL) |
| | | if (pSideData == NULL) |
| | | return; |
| | | |
| | | int nStageNo = g_pBase->m_nStageNo; |
| | | |
| | | if(nStageNo < 0 || nStageNo > 1) |
| | | if (nStageNo < 0 || nStageNo > 1) |
| | | nStageNo = 0; |
| | | |
| | | int nGlassSize = (int) (((double) m_pRecipe->m_SideParam[(int) emDim].m_nSidePanelSize_um) / pCamera->m_dScanResolution[nStageNo]); |
| | | int nGlassSize = (int)(((double)m_pRecipe->m_SideParam[(int)emDim].m_nSidePanelSize_um) / pCamera->m_dScanResolution[nStageNo]); |
| | | |
| | | pSideData->m_nPreGlassEndLine = pSideData->m_nGlassStartLine + nGlassSize; |
| | | pSideData->m_nPreGlassEndFrame = pSideData->m_nPreGlassEndLine/pCamera->m_FrameSize.cy; |
| | | pSideData->m_nPreGlassEndFrame = pSideData->m_nPreGlassEndLine / pCamera->m_FrameSize.cy; |
| | | |
| | | g_pStatus->SetGrabFrametoScan(iScan,pSideData->m_nPreGlassEndFrame+5); |
| | | g_pStatus->SetGrabFrametoScan(iScan, pSideData->m_nPreGlassEndFrame + 5); |
| | | |
| | | g_pLog->DisplayMessage(_T("%s Scan %d : Set Grab EndFrame - GlassEnd %d, Frame %d, GrabBuf %d"),PANEL_SIDE[emDim],iScan,pSideData->m_nPreGlassEndLine,pSideData->m_nPreGlassEndFrame,pSideData->m_nPreGlassEndFrame+5); |
| | | g_pLog->DisplayMessage(_T("%s Scan %d : Set Grab EndFrame - GlassEnd %d, Frame %d, GrabBuf %d"), PANEL_SIDE[emDim], iScan, pSideData->m_nPreGlassEndLine, pSideData->m_nPreGlassEndFrame, pSideData->m_nPreGlassEndFrame + 5); |
| | | } |
| | | |
| | | BOOL CInspectCamera::FindGlassStartLine(DimensionDir emDim,stFrameIndex stFrame) |
| | | { |
| | | BOOL CInspectCamera::FindGlassStartLine(DimensionDir emDim, stFrameIndex stFrame) |
| | | { |
| | | CSide_Data* pSideData = m_pGlassData->GetSideData(emDim); |
| | | if(pSideData == NULL) |
| | | if (pSideData == NULL) |
| | | return FALSE; |
| | | |
| | | CCameraSettings *pCamera = m_pHardparm->GetCameraSettings(m_iCamera,stFrame.nScanIdx); |
| | | if(pCamera == NULL) |
| | | CCameraSettings* pCamera = m_pHardparm->GetCameraSettings(m_iCamera, stFrame.nScanIdx); |
| | | if (pCamera == NULL) |
| | | return FALSE; |
| | | |
| | | int nFrame = m_pGrabber->GetFrameBuffer()->GetFrameCount()/2; |
| | | int nFrame = m_pGrabber->GetFrameBuffer()->GetFrameCount() / 2; |
| | | int nFrameWidth = pCamera->m_FrameSize.cx; |
| | | int nFrameHeight = pCamera->m_FrameSize.cy; |
| | | int nSkipFrame = 0; // EI... // (m_bSimulation == FALSE) ? 1 : 0; //pGlsInfo->m_nFindGlassStartOffset[emDim] / nFrameHeight; |
| | | int nSetHor = m_pRecipe->m_SideParam[(int) emDim].m_nFindStartEndLine_X_pxl; |
| | | int nSetHor = m_pRecipe->m_SideParam[(int)emDim].m_nFindStartEndLine_X_pxl; |
| | | |
| | | if(nSetHor < BOUNDARY_GLASSSTARTWIDTH / 2) nSetHor = BOUNDARY_GLASSSTARTWIDTH / 2; |
| | | if(nSetHor > nFrameWidth-(BOUNDARY_GLASSSTARTWIDTH / 2)) nSetHor = nFrameWidth-(BOUNDARY_GLASSSTARTWIDTH / 2); |
| | | if (nSetHor < BOUNDARY_GLASSSTARTWIDTH / 2) nSetHor = BOUNDARY_GLASSSTARTWIDTH / 2; |
| | | if (nSetHor > nFrameWidth - (BOUNDARY_GLASSSTARTWIDTH / 2)) nSetHor = nFrameWidth - (BOUNDARY_GLASSSTARTWIDTH / 2); |
| | | |
| | | // pSideData->nGlassEdgeXPos[0] = nSetHor; |
| | | |
| | | int j, k, nGab; |
| | | int nThreshold = m_pRecipe->m_SideParam[emDim].m_nFindStartEndLine_Threshold * BOUNDARY_GLASSSTARTWIDTH; |
| | | int *pnSum = new int[nFrameHeight + BOUNDARYHORIZ_LEVELDIST]; |
| | | int* pnSum = new int[nFrameHeight + BOUNDARYHORIZ_LEVELDIST]; |
| | | LPBYTE lpHeader; |
| | | int nCountinueCount = 0; |
| | | int nRet,nHStart; |
| | | int nRet, nHStart; |
| | | |
| | | DWORD dwT1 = GetTickCount(); |
| | | |
| | | g_pLog->DisplayMessage(_T("%s Find Glass Start Start : Scan %d "),PANEL_SIDE[emDim],stFrame.nScanIdx); |
| | | g_pLog->DisplayMessage(_T("%s Find Glass Start Start : Scan %d "), PANEL_SIDE[emDim], stFrame.nScanIdx); |
| | | |
| | | for(int iFrame=0;iFrame<nFrame;iFrame++) |
| | | for (int iFrame = 0; iFrame < nFrame; iFrame++) |
| | | { |
| | | while (TRUE) |
| | | { |
| | | nRet = m_pGrabber->IsAcqFrame(iFrame); |
| | | if (nRet < 2) // 酒流 救嘛躯栏骨肺 措扁. |
| | | if (nRet < 2) // 아직 안찍혔으므로 대기. |
| | | { |
| | | if (GetTickCount() - dwT1 > TIME_WAIT_GLASS_START) |
| | | { |
| | | g_pLog->DisplayMessage(_T("%s Find Glass Start : no image(Grab Time Out),%d sec"),PANEL_SIDE[emDim],TIME_WAIT_GLASS_START/1000); |
| | | delete [] pnSum; |
| | | g_pLog->DisplayMessage(_T("%s Find Glass Start : no image(Grab Time Out),%d sec"), PANEL_SIDE[emDim], TIME_WAIT_GLASS_START / 1000); |
| | | delete[] pnSum; |
| | | return FALSE; |
| | | } |
| | | Sleep(1); |
| | | } |
| | | } |
| | | else |
| | | break; |
| | | |
| | | } |
| | | if (nSkipFrame > iFrame) |
| | | continue; |
| | | continue; |
| | | |
| | | lpHeader = m_pGrabber->GetFrameHeader(stFrame.nScanIdx,iFrame); |
| | | if(lpHeader == NULL) |
| | | lpHeader = m_pGrabber->GetFrameHeader(stFrame.nScanIdx, iFrame); |
| | | if (lpHeader == NULL) |
| | | { |
| | | g_pLog->DisplayMessage(_T("%s Find Glass Start : no image(Image is Null)"),PANEL_SIDE[emDim]); |
| | | delete [] pnSum; |
| | | g_pLog->DisplayMessage(_T("%s Find Glass Start : no image(Image is Null)"), PANEL_SIDE[emDim]); |
| | | delete[] pnSum; |
| | | return FALSE; |
| | | } |
| | | |
| | |
| | | { |
| | | for (k = nHStart; k < nHStart + BOUNDARY_GLASSSTARTWIDTH; k++) |
| | | { |
| | | // Grab牢 版快 滚欺狼 版拌俊辑 1024扼牢阑 逞绢哎 版快 促澜 滚欺甫 啊廉客具 茄促. |
| | | // Grab인 경우 버퍼의 경계에서 1024라인을 넘어갈 경우 다음 버퍼를 가져와야 한다. |
| | | if (j == nFrameHeight && nLine != 0 && bChangeBuffer == FALSE) |
| | | { |
| | | { |
| | | DWORD dwTick = GetTickCount(); |
| | | while (TRUE) |
| | | { |
| | | if(GetTickCount()-dwTick > TIME_WAIT_GLASS_START/2) |
| | | { |
| | | g_pLog->DisplayMessage(_T("%s No Image"),PANEL_SIDE[emDim]); |
| | | delete [] pnSum; |
| | | { |
| | | if (GetTickCount() - dwTick > TIME_WAIT_GLASS_START / 2) |
| | | { |
| | | g_pLog->DisplayMessage(_T("%s No Image"), PANEL_SIDE[emDim]); |
| | | delete[] pnSum; |
| | | return FALSE; |
| | | } |
| | | |
| | | if(m_pGrabber->IsAcqFrame(iFrame + 1) > 1) |
| | | if (m_pGrabber->IsAcqFrame(iFrame + 1) > 1) |
| | | { |
| | | lpHeader = m_pGrabber->GetFrameHeader(stFrame.nScanIdx,iFrame + 1); |
| | | if(lpHeader != NULL) |
| | | lpHeader = m_pGrabber->GetFrameHeader(stFrame.nScanIdx, iFrame + 1); |
| | | if (lpHeader != NULL) |
| | | { |
| | | bChangeBuffer = TRUE; |
| | | //g_pLog->DisplayMessage(_T("%s Change Buffer %d, %d, %d"),PANEL_SIDE[pRecipe->GetDimension()], j, i, g_pBase->m_pMemFrameNo[GetCameraID()]); |
| | | break; |
| | | } |
| | | } |
| | | } |
| | | } |
| | | } |
| | | } |
| | | nLine = 0; |
| | | } |
| | | |
| | | pnSum[j] += *(lpHeader + nLine * nFrameWidth + k); |
| | | } |
| | | nLine++; |
| | | nLine++; |
| | | |
| | | if (j >= BOUNDARYHORIZ_LEVELDIST) |
| | | { |
| | | nGab = abs(pnSum[j - BOUNDARYHORIZ_LEVELDIST] - pnSum[j]); |
| | | nGab = abs(pnSum[j - BOUNDARYHORIZ_LEVELDIST] - pnSum[j]); |
| | | if (nGab > nThreshold) |
| | | nCountinueCount++; |
| | | else |
| | |
| | | |
| | | if (nCountinueCount >= 2) |
| | | { |
| | | g_pLog->DisplayMessage(_T("%s Start Line Frame %d, Line %d, Gab %d, Thres %d"), PANEL_SIDE[emDim],iFrame, j, nGab, nThreshold); |
| | | // Glass狼 矫累瘤痢阑 茫酒辑 备炼眉俊 持绰促. |
| | | g_pLog->DisplayMessage(_T("%s Start Line Frame %d, Line %d, Gab %d, Thres %d"), PANEL_SIDE[emDim], iFrame, j, nGab, nThreshold); |
| | | // Glass의 시작지점을 찾아서 구조체에 넣는다. |
| | | pSideData->m_nGlassStartLine = iFrame * nFrameHeight + j - 2; |
| | | pSideData->m_nGlassStartFrame = pSideData->m_nGlassStartLine/nFrameHeight; |
| | | pSideData->m_nGlassStartFrame = pSideData->m_nGlassStartLine / nFrameHeight; |
| | | pSideData->m_bFindGlassStartLine = TRUE; |
| | | // Log |
| | | g_pLog->DisplayMessage(_T("")); |
| | | g_pLog->DisplayMessage(_T("%s Glass StartLine :: Pixel %ld nFrameNo=%d") |
| | | , PANEL_SIDE[emDim] |
| | | , pSideData->m_nGlassStartLine |
| | | , pSideData->m_nGlassStartLine / nFrameHeight); |
| | | , pSideData->m_nGlassStartLine |
| | | , pSideData->m_nGlassStartLine / nFrameHeight); |
| | | |
| | | delete [] pnSum; |
| | | delete[] pnSum; |
| | | |
| | | // 22.07.24 |
| | | // SaveGlassLineImage(stFrame.nScanIdx,pSideData->m_nGlassStartLine,nSetHor,emDim,_T("StartLine")); |
| | | MakeNotchArea(emDim); |
| | | |
| | | // Make Judge Line |
| | | pSideData->m_nCenterJudgeArea_Start = pSideData->m_nGlassStartLine + m_pRecipe->m_SideParam[(int) emDim].m_nCenterJudgeArea_StartLine_To_Start_pxl; |
| | | pSideData->m_nCenterJudgeArea_End = pSideData->m_nGlassStartLine + m_pRecipe->m_SideParam[(int) emDim].m_nCenterJudgeArea_StartLine_To_End_pxl; |
| | | pSideData->m_nCenterJudgeArea_Start = pSideData->m_nGlassStartLine + m_pRecipe->m_SideParam[(int)emDim].m_nCenterJudgeArea_StartLine_To_Start_pxl; |
| | | pSideData->m_nCenterJudgeArea_End = pSideData->m_nGlassStartLine + m_pRecipe->m_SideParam[(int)emDim].m_nCenterJudgeArea_StartLine_To_End_pxl; |
| | | |
| | | return TRUE; |
| | | } |
| | |
| | | } |
| | | } |
| | | |
| | | delete [] pnSum; |
| | | delete[] pnSum; |
| | | return FALSE; |
| | | } |
| | | |
| | | BOOL CInspectCamera::MakeNotchArea(DimensionDir emDim) |
| | | { |
| | | if(m_pGlassData == NULL || m_pRecipe == NULL) |
| | | if (m_pGlassData == NULL || m_pRecipe == NULL) |
| | | return FALSE; |
| | | |
| | | CSide_Data* pSideData = m_pGlassData->GetSideData(emDim); |
| | | |
| | | if(pSideData == NULL) |
| | | if (pSideData == NULL) |
| | | return FALSE; |
| | | |
| | | if(pSideData->m_bFindGlassStartLine == FALSE) |
| | | if (pSideData->m_bFindGlassStartLine == FALSE) |
| | | return FALSE; |
| | | |
| | | int nNotchCount = m_pRecipe->m_SideParam[(int) emDim].m_nNotchCount; |
| | | int nNotchCount = m_pRecipe->m_SideParam[(int)emDim].m_nNotchCount; |
| | | |
| | | pSideData->m_nNotchCount = nNotchCount; |
| | | |
| | | g_pLog->DisplayMessage(_T("Make Notch Area - Side[%s] Notch Count[%d]"), g_SideName[(int) emDim], nNotchCount); |
| | | g_pLog->DisplayMessage(_T("Make Notch Area - Side[%s] Notch Count[%d]"), g_SideName[(int)emDim], nNotchCount); |
| | | |
| | | for(int i=0; i<nNotchCount; i++) |
| | | for (int i = 0; i < nNotchCount; i++) |
| | | { |
| | | if(MAX_SIDE_NOTCH_COUNT <= i) |
| | | if (MAX_SIDE_NOTCH_COUNT <= i) |
| | | break; |
| | | |
| | | int nStartLine_Offset = pSideData->m_nGlassStartLine - m_pRecipe->m_SideParam[(int) emDim].m_NotchPrm[i].m_nGlassStartLine_pxl; |
| | | int nStartLine_Offset = pSideData->m_nGlassStartLine - m_pRecipe->m_SideParam[(int)emDim].m_NotchPrm[i].m_nGlassStartLine_pxl; |
| | | |
| | | pSideData->m_rtNotchArea_pxl[i] = m_pRecipe->m_SideParam[(int) emDim].m_NotchPrm[i].m_rtNotch_Area_pxl; |
| | | pSideData->m_rtNotchArea_pxl[i] = m_pRecipe->m_SideParam[(int)emDim].m_NotchPrm[i].m_rtNotch_Area_pxl; |
| | | |
| | | pSideData->m_rtNotchArea_pxl[i].OffsetRect(0, nStartLine_Offset); |
| | | } |
| | |
| | | return TRUE; |
| | | } |
| | | |
| | | BOOL CInspectCamera::ProcessFrame(int iThread,DimensionDir emDim,stFrameIndex stFrame) |
| | | BOOL CInspectCamera::ProcessFrame(int iThread, DimensionDir emDim, stFrameIndex stFrame) |
| | | { |
| | | try { |
| | | // 1. Find End Line.. (Corner甫 力寇茄 Side扼牢阑 茫扁 困秦 End Line何磐 茫绰促) |
| | | // 1. Find End Line.. (Corner를 제외한 Side라인을 찾기 위해 End Line부터 찾는다) |
| | | FindEndLine(iThread, emDim, stFrame); |
| | | |
| | | // 2. Find Side Line.. (秦寸 橇饭烙俊辑 Corner/Notch 甫 力寇茄 Side 扼牢 茫扁) |
| | | // 2. Find Side Line.. (해당 프레임에서 Corner/Notch 를 제외한 Side 라인 찾기) |
| | | #if USE_AI_DETECT |
| | | FindSideLine(iThread, emDim, stFrame); |
| | | #else |
| | |
| | | |
| | | int CInspectCamera::GetDefectCount() |
| | | { |
| | | if(m_pDefectControl == NULL) |
| | | if (m_pDefectControl == NULL) |
| | | return 0; |
| | | |
| | | return m_pDefectControl->GetDefectCount(); |
| | | } |
| | | |
| | | CDefect *CInspectCamera::GetDefect(int iDefect) |
| | | CDefect* CInspectCamera::GetDefect(int iDefect) |
| | | { |
| | | if(m_pDefectControl == NULL) |
| | | if (m_pDefectControl == NULL) |
| | | return NULL; |
| | | |
| | | return m_pDefectControl->GetDefect(iDefect); |
| | |
| | | if (m_wsClients != nullptr) |
| | | { |
| | | m_wsClients->set_message_handler([this](const std::string& msg) { |
| | | // JSON 格式 |
| | | // JSON 목駕 |
| | | if (!msg.empty() && msg.size() > 3) { |
| | | try { |
| | | nlohmann::json json_data = nlohmann::json::parse(msg); |
| | |
| | | DimensionDir emDim = (DimensionDir)(json_data.value("nLineType", 0) - 1); |
| | | WSReceiveData wsReceiveData; |
| | | |
| | | // 解析 JSON 数据并填充 wsReceiveData |
| | | // 썩驕 JSON 鑒앴깻輕념 wsReceiveData |
| | | wsReceiveData.nRecipe = json_data.value("Reciepe", 0); |
| | | wsReceiveData.nLineType = json_data.value("nLineType", 0); |
| | | wsReceiveData.nIndex = json_data.value("nIndex", 0); |
| | |
| | | wsReceiveData.nFrameIdx = json_data.value("nFrameIdx", 0); |
| | | wsReceiveData.strSN = json_data.value("SN", ""); |
| | | wsReceiveData.dTimeStamp = json_data.value("TimeStamp", 0.0); |
| | | wsReceiveData.nGNum = json_data.value("NGnum", 0); // NG 数量 |
| | | wsReceiveData.nGNum = json_data.value("NGnum", 0); // NG 鑒좆 |
| | | |
| | | // 格式化并显示基本信息 |
| | | // 목駕뺏깻鞫刻샘굶斤口 |
| | | CString strText; |
| | | strText.Format(_T("Reciepe: %d, LineType: %d, Index: %d, SN: %s, NGNum: %d, TimeStamp: %f\n"), |
| | | wsReceiveData.nRecipe, wsReceiveData.nLineType, wsReceiveData.nIndex, wsReceiveData.strSN.c_str(), wsReceiveData.nGNum, wsReceiveData.dTimeStamp); |
| | | |
| | | if (wsReceiveData.nLineType > 0 |
| | | && wsReceiveData.nLineType < 9 |
| | | if (wsReceiveData.nLineType > 0 |
| | | && wsReceiveData.nLineType < 9 |
| | | && wsReceiveData.nGNum != 0 |
| | | && g_pBase->m_strHPanelID.Compare(CString(wsReceiveData.strSN.c_str())) == 0) |
| | | { |
| | | // 遍历并填充 ngPosArray |
| | | // 깁저깻輕념 ngPosArray |
| | | auto ngPosArray = json_data["NGPosArray"]; |
| | | for (auto& ngPos : ngPosArray) { |
| | | WSReceiveData::NGPosition ngPosition; |
| | |
| | | g_pLog->DisplayMessage(strText); |
| | | } |
| | | catch (const nlohmann::json::parse_error& e) { |
| | | // 处理 JSON 解析错误 |
| | | // 뇹잿 JSON 썩驕댄轎 |
| | | std::cerr << "JSON parse error: " << e.what() << std::endl; |
| | | } |
| | | } |
| | | else { |
| | | // 处理空消息 |
| | | // 뇹잿왕句口 |
| | | std::cerr << "Empty message" << std::endl; |
| | | } |
| | | }); |
| | | }); |
| | | } |
| | | } |
| | | |
| | |
| | | |
| | | std::string jsonMetadata = CreateJsonWSSendData(wsData); |
| | | |
| | | // 预先分配内存,减少动态扩容 |
| | | // 渡邱롸토코닸,숑 帽檄윈휭 |
| | | std::vector<char> message; |
| | | message.reserve(jsonMetadata.size() + width * height); |
| | | |
| | | // 插入 JSON 数据和图像数据 |
| | | // 꿨흙 JSON 鑒앴뵨暠獗鑒앴 |
| | | message.insert(message.end(), jsonMetadata.begin(), jsonMetadata.end()); |
| | | message.insert(message.end(), data, data + width * height); |
| | | |
| | | // 使用 std::move 传递 message,避免拷贝 |
| | | // 賈痰 std::move 눈뒵 message,긁출옙굔 |
| | | bool isSucceed = m_wsClients->send_binary_to_idle_client_with_retry(std::move(message), 1000, 50); |
| | | if (!isSucceed) |
| | | { |
| | | { |
| | | CDefect_Info defectInfo; |
| | | CRect rtDefectPos_pxl(left, top, left + width, top + height); |
| | | defectInfo.m_iFrameIdx = stFrame.nFrameIdx; |
| | |
| | | for (int i = 0; i < rtProcessArea.Height(); i++) |
| | | memcpy(pDefectProcessImage.GetDataAddress(0, i), frameBuffer.GetDataAddress(rtProcessArea.left, i), rtProcessArea.Width()); |
| | | |
| | | // 发送从临时缓冲区中获取的数据 |
| | | // 랙箇닖줄珂뻠녑혐櫓삿혤돨鑒앴 |
| | | int state = (stFrame.nFrameIdx == 0) ? 1 : (pDefectProcessImage.GetHeight() < IMAGE_HEIGHT ? 2 : 3); |
| | | SendImageDataOverWebSocket(eDim, stFrame, stFrame.nFrameIdx, pDefectProcessImage.GetDataAddress(0, 0), state, nCutLine, vecInspectAreaList[nRegionIdx].top, pDefectProcessImage.GetWidth(), pDefectProcessImage.GetHeight()); |
| | | |
| | |
| | | |
| | | #if USE_AI_DETECT |
| | | void CInspectCamera::SetUseAIDetect(bool bUseAIDetect) |
| | | { |
| | | { |
| | | m_bUseAIDetect = bUseAIDetect; |
| | | } |
| | | |
| | |
| | | rtProcessArea.bottom += nHeightOff; |
| | | } |
| | | |
| | | // 保证图像高度为4的倍数 |
| | | // 괏聯暠獗멕똑槨4돨굡鑒 |
| | | nHeightOff = rtProcessArea.Height() % 4; |
| | | if (nHeightOff != 0) |
| | | { |
| | |
| | | |
| | | myLoc.Lock(); |
| | | long long dStartTime = GetCurrentTimestamp(); |
| | | // 发送从临时缓冲区中获取的数据 |
| | | // 랙箇닖줄珂뻠녑혐櫓삿혤돨鑒앴 |
| | | std::vector<AiDetectResult> results; |
| | | if (m_pAiDetectEx->detect(frame, results, m_strChannel)) { |
| | | for (auto& result : results) { |