//--------------------------------------------------------------------------- /** * @fn public fn_GetSearchResult * @brief Search 결과 얻기. * @return ST_ALIGN_RESULT * @param void * @remark * - Search 결과 얻기. * @author 선경규(Kyeong Kyu - Seon) * @date 2020/2/9 20:01 */ public ST_ALIGN_RESULT fn_GetSearchResult() { IntPtr pResult = Marshal.AllocHGlobal(Marshal.SizeOf(_stResult)); Marshal.StructureToPtr(_stResult, pResult, true); libGetResult(pResult); fn_WriteLog(this.Title + " : Get Result.", UserEnum.EN_LOG_TYPE.ltVision); _stResult = (ST_ALIGN_RESULT)Marshal.PtrToStructure(pResult, typeof(ST_ALIGN_RESULT)); return(_stResult); }
public bool fn_PinSearch(double posx, double posy, int nPos, WriteableBitmap img = null) { bool bRtn = false; _Pos.Count = nPos; if (_Pos.Count == 0) { _DateTime = DateTime.Now; } // Position 처리. _Pos.GrabPos[_Pos.Count].X = posx; _Pos.GrabPos[_Pos.Count].Y = posy; string strPath = $"D:\\Image\\{_DateTime:yyyyMMdd}\\ToolStorage\\"; // Image 처리. if (img == null) { img = UserClass.g_VisionManager._CamManager.fn_GetFrame(); } if (img == null) { return(bRtn); } // Image Save. if (!Directory.Exists(strPath)) { Directory.CreateDirectory(strPath); } try { using (FileStream stream = new FileStream(strPath + $"{_DateTime:yyyyMMdd_HHmm}_Pin{_Pos.Count + 1}_{posx:F3}_{posy:F3}.bmp", FileMode.Create)) { BmpBitmapEncoder encoder = new BmpBitmapEncoder(); encoder.Frames.Add(BitmapFrame.Create(img)); encoder.Save(stream); fn_WriteLog(this.Title + $"Image Saved. {stream.Name}", UserEnum.EN_LOG_TYPE.ltVision); } } catch (Exception ex) { fn_WriteLog(ex.Message, UserEnum.EN_LOG_TYPE.ltVision); Console.WriteLine(ex.Message); } libSetImage(img.BackBuffer, img.PixelWidth, img.PixelHeight, img.Format.BitsPerPixel / 8); // 원 지름 : 210, 스무딩 : 99% libPinSearch(UserClass.g_VisionManager._RecipeVision.PinRadiusPixel, UserClass.g_VisionManager._RecipeVision.PinSmooth); IntPtr pResult = Marshal.AllocHGlobal(Marshal.SizeOf(_stResult)); Marshal.StructureToPtr(_stResult, pResult, true); libGetResult(pResult); fn_WriteLog(this.Title + " : Get Result.", UserEnum.EN_LOG_TYPE.ltVision); _stResult = (ST_ALIGN_RESULT)Marshal.PtrToStructure(pResult, typeof(ST_ALIGN_RESULT)); int nMaxScorePos = -1; double dMaxValue = 0.0; if (_stResult.NumOfFound > 0) { for (int resultcnt = 0; resultcnt < _stResult.NumOfFound; resultcnt++) { if (_stResult.stResult[resultcnt].dScore > dMaxValue) { dMaxValue = _stResult.stResult[resultcnt].dScore; nMaxScorePos = resultcnt; } } if (nMaxScorePos > -1) { _Pos.SearchPos[_Pos.Count].X = _stResult.stResult[nMaxScorePos].dX; _Pos.SearchPos[_Pos.Count].Y = _stResult.stResult[nMaxScorePos].dY; fn_WriteLog(this.Title + $"Index : {_Pos.Count} Search X : {_Pos.SearchPos[_Pos.Count].X}, Search Y : {_Pos.SearchPos[_Pos.Count].Y}", UserEnum.EN_LOG_TYPE.ltVision); _Pos.Count++; bRtn = true; } } fn_WriteLog(this.Title + $"Searched Num : {_stResult.NumOfFound}, MAX Score Pos : {nMaxScorePos}", UserEnum.EN_LOG_TYPE.ltVision); return(bRtn); }
private void bn_Inspection_Click(object sender, RoutedEventArgs e) { fn_Update(); WriteableBitmap wb = ac_Align.fn_GetImageStream(true); if (wb != null) { ST_ALIGN_RESULT result = new ST_ALIGN_RESULT(); result.stResult = new ST_RESULT[5]; //g_VisionManager._ImgProc.EPDResult(wb, _ModelRecipe.Inspection, ref StartY, ref EndY, ref MaxIdx); bool bRtn = g_VisionManager._ImgProc.EPDResult(wb, _ModelRecipe.Inspection, ref result); //ac_Align.fn_SetResult(result); //_ModelRecipe.Inspection.RefDistance // dScore = cy double dResult1 = result.stResult[1].dScore - result.stResult[0].dScore; double dResult2 = result.stResult[2].dScore - result.stResult[1].dScore; dResult1 *= UserClass.g_VisionManager._RecipeVision.ResolutionY / 1000; // mm scale dResult2 *= UserClass.g_VisionManager._RecipeVision.ResolutionY / 1000; // mm scale bool bResult1 = false; bool bResult2 = false; bool bResult = false; if (_ModelRecipe.Inspection.Section1 == 0)//result <= target { bResult1 = dResult1 <= _ModelRecipe.Inspection.RefDistance; } else if (_ModelRecipe.Inspection.Section1 == 1)//result >= target { bResult1 = dResult1 >= _ModelRecipe.Inspection.RefDistance; } if (_ModelRecipe.Inspection.Section2 == 0)//result <= target { bResult2 = dResult2 <= _ModelRecipe.Inspection.RefDistance2; } else if (_ModelRecipe.Inspection.Section2 == 1)//result >= target { bResult2 = dResult2 >= _ModelRecipe.Inspection.RefDistance2; } switch (_ModelRecipe.Inspection.Condition) { case 0: //Only 1 bResult = bResult1; break; case 1: //Only 2 bResult = bResult2; break; case 2: // Or bResult = bResult1 && bResult2; break; case 3: // And bResult = bResult1 || bResult2; break; } up_Result1.UPValue = $"{dResult1:F3}"; up_Result2.UPValue = $"{dResult2:F3}"; if (bResult1) { up_Result1.UPValueBackground = Brushes.Green; } else { up_Result1.UPValueBackground = Brushes.Red; } if (bResult2) { up_Result2.UPValueBackground = Brushes.Green; } else { up_Result2.UPValueBackground = Brushes.Red; } if (bResult) { ug_Section1.Background = Brushes.Green; ug_Section2.Background = Brushes.Green; } else { ug_Section1.Background = Brushes.Red; ug_Section2.Background = Brushes.Red; } } }
/** * @fn public bool EPDResult(WriteableBitmap wImg, ST_INSPECTION stparam, re ST_ALIGN_RESULT result) * @brief EPD Processing (Edge Point Detect) * @return bool : EPD 결과. * @param WriteableBitmap wImg : 입력 이미지 * @param ST_INSPECTION stparam : EPD Parameter * @param ref ST_ALIGN_RESULT result : 결과 구조체 * @remark * - EPD는 이미지 상단부터 구간을 정의함. * - Y값이 작은값부터 순서대로 index 부여. * - index 0 - 1 1구간. * - index 1 - 2 2구간. * - 상단부터 2구간의 조건만 확인함. * - DLL에서 Image Log 저장. * @author 선경규(Kyeong Kyu - Seon) * @date 2020/10/6 10:28 */ public bool EPDResult(WriteableBitmap wImg, ST_INSPECTION stparam, ref ST_ALIGN_RESULT result, bool bAuto = true) { bool bRtn = false; try { int StartY = 0; int EndY = 0; int CY = 0; int nCount = 0; CannyEdge(wImg, stparam); IntPtr ptrParam = IntPtr.Zero; ptrParam = Marshal.AllocHGlobal(Marshal.SizeOf(stparam)); Marshal.StructureToPtr(stparam, ptrParam, false); int nSecCount = libProcMeasureLen(ptrParam, bAuto); if (nSecCount > 0) { fn_WriteLog(this.Title + $" : Detect Section ( {nSecCount} ).", UserEnum.EN_LOG_TYPE.ltVision); nCount = nSecCount < result.stResult.Length ? nSecCount : result.stResult.Length; for (int i = 0; i < nCount; i++) { libGetMeasureLen(ref StartY, ref EndY, ref CY, i); if (result.stResult != null) { result.stResult[i] = new ST_RESULT(); result.stResult[i].dWidth = 200; result.stResult[i].dHeight = EndY - StartY; result.stResult[i].dX = stparam.ROIX; result.stResult[i].dY = stparam.ROIY + StartY + result.stResult[i].dHeight / 2.0; // dScore = cy result.stResult[i].dScore = stparam.ROIY + CY; } if (StartY == -2 && EndY == -2) { fn_WriteLog(this.Title + " : Index Out of Range", UserEnum.EN_LOG_TYPE.ltVision); break; } } double dResult1 = result.stResult[1].dScore - result.stResult[0].dScore; double dResult2 = result.stResult[2].dScore - result.stResult[1].dScore; dResult1 *= UserClass.g_VisionManager._RecipeVision.ResolutionY / 1000; // mm scale dResult2 *= UserClass.g_VisionManager._RecipeVision.ResolutionY / 1000; // mm scale bool bResult1 = false; bool bResult2 = false; if (stparam.Section1 == 0)//result <= target { bResult1 = dResult1 <= stparam.RefDistance; } else if (stparam.Section1 == 1)//result >= target { bResult1 = dResult1 >= stparam.RefDistance; } if (stparam.Section2 == 0)//result <= target { bResult2 = dResult2 <= stparam.RefDistance2; } else if (stparam.Section2 == 1)//result >= target { bResult2 = dResult2 >= stparam.RefDistance2; } switch (stparam.Condition) { case 0: //Only 1 bRtn = bResult1; break; case 1: //Only 2 bRtn = bResult2; break; case 2: // Or bRtn = bResult1 && bResult2; break; case 3: // And bRtn = bResult1 || bResult2; break; } } else if (nSecCount == -1) { fn_WriteLog(this.Title + " : Please Set ROI Image.", UserEnum.EN_LOG_TYPE.ltVision); } else { fn_WriteLog(this.Title + " : Can't Detect Section.", UserEnum.EN_LOG_TYPE.ltVision); } } catch (Exception ex) { fn_WriteLog(this.Title + " : " + ex.Message, UserEnum.EN_LOG_TYPE.ltVision); } return(bRtn); }