using MilCommon; using VisionCommon; using Matrox.MatroxImagingLibrary; using System; using System.Collections.Generic; using Hermes; using System.IO; using Newtonsoft.Json; using System.Linq; using System.Windows; namespace MilPattern { public class MilPatternAgent : PatternAgentBase { /// /// MIL 패턴 에이전트 /// public MilPatternAgent( FovInfo fovInfo) : base(fovInfo) { LoadPatterns(); SetObservable(); } private void SetObservable() { var observable = VisionEventId.GetRecipeActivatedObservable(); observable.Subscribe(_ => LoadPatterns()); } public override Dictionary GetPatterns() { return _patterns; } #region Main Patterns public override List GetMainPatterns(SubSysInfo subSysInfo, eFovId fovId) { var fovIdxPrefix = PatternIndex.GetPrefix(subSysInfo.UnitId, subSysInfo.SubSysId, fovId); return GetMainPatterns(fovIdxPrefix); } public override List GetMainPatterns(FovInfo fovInfo) { var fovIdxPrefix = PatternIndex.GetPrefix(fovInfo.UnitId, fovInfo.SubSysId, fovInfo.FovId); return GetMainPatterns(fovIdxPrefix); } #endregion public override PatternInfo GetPatternInfo(FovInfo fovInfo, int patternId) { return GetPatternInfo( new PatternIndex(fovInfo.UnitId, fovInfo.SubSysId, fovInfo.FovId, patternId)); } public override string GetPatternInfoPath() { if (VisionSettingManager.VisionSetting.UseCamPattern) { return VisionEnv.VisionRootDataPath; } else { return PatternConstants.GetCurrentRecipeFilePath(); } } /// /// 패턴 가져오기 /// /// 패턴 public override int LoadPatterns() { if (!MilEnvironment.Instance.HasValidLicense()) { _logger.I("No MIL license"); return E1.GENERIC; } if (E1.OK != ClearPatterns(_patterns)) { return E1.GENERIC; } if (E1.OK != LoadPatterns(_patterns)) { return E1.GENERIC; } return E1.OK; } public override int CopyPattern(PatternIndex sourcePatternIndex, PatternIndex dstPatternIndex) { // 1. Copy string curRecipePath = GetPatternInfoPath(); string sourcePatternPath = Path.Combine(new string[] { curRecipePath, PatternConstants.DIR_NAME_PATTERN, sourcePatternIndex.GetSubPatternDirectoryPath() }); string dstPatternPath = Path.Combine(new string[] { curRecipePath, PatternConstants.DIR_NAME_PATTERN, dstPatternIndex.GetSubPatternDirectoryPath() }); // 2. Remove old dst pattern if (E1.OK != Remove(dstPatternIndex)) { _logger.FuncE($"Remove error"); return E1.GENERIC; } // 3. Copy pattern files if (E1.OK != CopyPatternFiles(sourcePatternPath, dstPatternPath)) { _logger.FuncE($"CopyPatternFiles error"); return E1.GENERIC; } // 4. Reload copied pattern files var patternInfoFilePath = Path.Combine(dstPatternPath, PatternConstants.FILE_NAME_PATTERN_INFO); if (!File.Exists(patternInfoFilePath)) { _logger.FuncE($"patternInfoFilePath does NOT exist : {patternInfoFilePath}"); return E1.GENERIC; } var sourcePatternInfo = GetPatternInfo(sourcePatternIndex); var dstPatternInfo = LoadPatternInfoFromFile(patternInfoFilePath); dstPatternInfo.MilSystemId = sourcePatternInfo.MilSystemId; dstPatternInfo.PatternIndex = dstPatternIndex.Clone() as PatternIndex; return ReloadPattern(dstPatternInfo); } public override object GetTool(PatternInfo patternInfo) { throw new NotImplementedException(); // 미사용 } #region Find for Sequence public override PatternResult FindPattern( PatternInfo patternInfo, object image, ICameraDisplay cameraDisplay, FixtureResult fixtureResult) { var findImage = (MIL_ID)image; var patternResult = new PatternResult(); var pattern = _patterns[patternInfo]; if (((PatternBase)pattern).IsDirty()) { ((PatternBase)pattern).CleanDirty(); pattern.Load(); } ROI fixtureRoi = GetFixtureROI(patternInfo, fixtureResult); patternResult.FindRoi = fixtureRoi.Clone() as ROI; if (!patternInfo.IsActivated) { _logger.I($"{patternInfo} : NOT activated"); patternResult = pattern.GetNotFoundPatternResult(); } else { if (patternInfo.PreProcParam.Enabled()) { MIL_ID preProcImage = MIL.M_NULL; try { preProcImage = ImgPreProcessor.GetPreProcessedImage(findImage, patternInfo.PreProcParam); patternResult = Find(patternInfo, preProcImage, fixtureRoi); CopyImageToDisplay(cameraDisplay as IMilCameraDisplay, preProcImage); } catch (Exception e) { _logger.I($"{e.Message}"); } finally { MilEnvironment.FreeImage(preProcImage); } } else { patternResult = Find(patternInfo, findImage, fixtureRoi); } } if (patternResult.Status == eFoundStatus.FoundOK) { foreach (var reuslt in patternResult.Results) { _logger.I($"{patternInfo} : {patternResult.Status} : {reuslt}"); } } else { _logger.I($"{patternInfo} : {patternResult.Status}"); } SetPatternParams(patternInfo, patternResult); if (patternResult.PatternType == ePatternType.LineFinder) { SetLineCenterPoint(patternResult, patternInfo, cameraDisplay); } return patternResult; } private void CopyImageToDisplay(IMilCameraDisplay milCameraDisplay, MIL_ID preProcImage) { var displayImage = milCameraDisplay.GetImage(); if (MilEnvironment.ImageSizeEquals(preProcImage, displayImage)) { MilEnvironment.CopyImage(preProcImage, displayImage); } } #endregion #region TestFind for Pattern Registration public override PatternResult FindPattern(PatternInfo patternInfo, object image, ROI findRoi = null) { var findImage = (MIL_ID)image; var patternResult = new PatternResult() { PatternIndex = patternInfo.GetPatternIndex().Clone() as PatternIndex, }; if (_patterns.ContainsKey(patternInfo)) { if (patternInfo.IsActivated) { var pattern = _patterns[patternInfo]; if (findRoi == null) { patternResult = pattern.Find(findImage); } else { patternResult = pattern.Find(findImage, findRoi); } patternResult.FindRoi = (findRoi != null) ? findRoi : GetFindROI(patternInfo); } else { _logger.I($"Pattern is not activated."); } } else { _logger.I($"Pattern does not exist."); } #if TEST_DEBUG Logger.W("TEST", $"[TEST] FindROI LEFTTOP : {patternResult.FindRoi.LeftTop.ToString()}, {patternResult.FindRoi.Center.ToString()}"); Logger.W("TEST", $"[TEST] FindROI WH : ({patternResult.FindRoi.Width}, {patternResult.FindRoi.Height}),({patternResult.FindRoi.Width/2}, {patternResult.FindRoi.Height/2})"); Logger.E("TEST", $"[TEST] Result : {patternResult.Results.FirstOrDefault()?.ImagePosition.X:F8}, {patternResult.Results.FirstOrDefault()?.ImagePosition.Y:F8}"); if(patternResult.Results.Count() >0 && patternResult.Results.FirstOrDefault() is ModelFinderResult modelFinderResult) { Logger.E("TEST", $"[TEST] Result Score : {modelFinderResult.Score:F8}"); } #endif SetPatternParams(patternInfo, patternResult); return patternResult; } public override PatternResult FindPatternBlock(PatternInfo patternInfo, object image, ROI findRoi = null) { var findImage = (MIL_ID)image; var patternResult = new PatternResult() { PatternIndex = patternInfo.GetPatternIndex().Clone() as PatternIndex, }; if (_patterns.ContainsKey(patternInfo)) { if (patternInfo.IsActivated) { var pattern = _patterns[patternInfo]; var patternBlock = pattern as IPatternBlock; var patternBlockResults = new List(); foreach (var patternId in patternBlock.GetPatternBlockIds()) { var curPatternIndex = patternInfo.GetPatternIndex().Clone() as PatternIndex; curPatternIndex.PatternId = patternId; var patterBlockPatternInfo = GetPatternInfo(curPatternIndex); var curPattern = GetPattern(patterBlockPatternInfo); PatternResult curPatternResult; if (findRoi == null) { curPatternResult = curPattern.Find(findImage); } else { curPatternResult = curPattern.Find(findImage, findRoi); } curPatternResult.FindRoi = (findRoi != null) ? findRoi : GetFindROI(patterBlockPatternInfo); SetPatternParams(patterBlockPatternInfo, curPatternResult); patternBlockResults.Add(curPatternResult); } patternResult = patternBlock.Find(patternBlockResults); patternResult.FindRoi = (findRoi != null) ? findRoi : GetFindROI(patternInfo); } else { _logger.I($"Pattern is not activated."); } } else { _logger.I($"Pattern does not exist."); } SetPatternParams(patternInfo, patternResult); return patternResult; } #endregion public override void Draw( PatternInfo patternInfo, PatternResult patternResult, ICameraDisplay cameraDisplay, bool isFixturePattern = false) { // Draw 택타임이 길어 비동기식으로 변경함. Application.Current.Dispatcher.BeginInvoke( new Action(() => { if (_patterns.ContainsKey(patternInfo)) { var milCameraDisplay = cameraDisplay as IMilCameraDisplay; IPatternFinder pattern; if (patternResult.Status != eFoundStatus.NotFound && patternResult.PatternIndex != null) { pattern = GetPattern(patternResult.PatternIndex); } else { pattern = _patterns[patternInfo]; } if (PatternConstants.IsPatternBlock(patternInfo.PatternType)) { DrawPatternBlockResult(pattern, patternResult, milCameraDisplay, isFixturePattern); } else { DrawPatternResult(pattern, patternResult, milCameraDisplay, isFixturePattern); } } })); } private void DrawPatternResult( IPatternFinder pattern, PatternResult patternResult, IMilCameraDisplay milCameraDisplay, bool isFixturePattern) { DrawFindROI(patternResult, milCameraDisplay, isFixturePattern); pattern.Draw(patternResult, milCameraDisplay, isFixturePattern); } private void DrawPatternBlockResult( IPatternFinder pattern, PatternResult patternResult, IMilCameraDisplay milCameraDisplay, bool isFixturePattern) { foreach (var patternBlockResult in patternResult.Results) { PatternResult line1PatternResult = null; PatternResult line2PatternResult = null; if (patternBlockResult.GetType() == typeof(LineIntersectionResult)) { var intersectionResult = patternBlockResult as LineIntersectionResult; line1PatternResult = intersectionResult.Line1PatternResult; line2PatternResult = intersectionResult.Line2PatternResult; } else if (patternBlockResult.GetType() == typeof(CaliperResult)) { var caliperResult = patternBlockResult as CaliperResult; line1PatternResult = caliperResult.PatternResultFirst; line2PatternResult = caliperResult.PatternResultSecond; } DrawFindROI(line1PatternResult, milCameraDisplay, isFixturePattern); DrawFindROI(line2PatternResult, milCameraDisplay, isFixturePattern); pattern.Draw(patternResult, milCameraDisplay, isFixturePattern); } } private void DrawFindROI( PatternResult patternResult, IMilCameraDisplay milCameraDisplay, bool isFixturePattern) { MIL_INT color = MIL.M_NULL; if (patternResult == null) { return; } if (patternResult.PatternType == ePatternType.Brightness && patternResult.Status == eFoundStatus.FoundOK) { color = ColorConverter.ConvertColor(eColor.Magenta); } else if (patternResult.PatternType == ePatternType.MultiLineFinder) { foreach (LineFinderResult lineFinderResult in patternResult.Results) { color = GraphicColors.GetFindRoiColor(lineFinderResult.Status, isFixturePattern); milCameraDisplay.AddPatternResultFindRoi(color, lineFinderResult.FindRoi); } return; } else if (patternResult.PatternType == ePatternType.MultiOcr) { foreach (OcrResult ocrResult in patternResult.Results) { color = GraphicColors.GetFindRoiColor(ocrResult.Status, isFixturePattern); milCameraDisplay.AddPatternResultFindRoi(color, ocrResult.FindRoi); } return; } else { color = GraphicColors.GetFindRoiColor(patternResult.Status, isFixturePattern); } milCameraDisplay.AddPatternResultFindRoi(color, patternResult.FindRoi); } public override IPatternFinder CreatePattern(PatternInfo patternInfo) { switch (patternInfo.PatternType) { case ePatternType.ImageModelFinder: return new ImageModelFinder(patternInfo); case ePatternType.ShapeModelFinder: return new ShapeModelFinder(patternInfo); case ePatternType.PatternMatching: return new PatternMatching(patternInfo); case ePatternType.LineFinder: case ePatternType.MultiLineFinder: return new LineFinder(patternInfo); case ePatternType.Caliper: return new Caliper(patternInfo); case ePatternType.EdgeFinder: return new EdgeFinder(patternInfo); case ePatternType.Blob: return new Blob(patternInfo); case ePatternType.Code: return new Code(patternInfo); case ePatternType.Ocr: case ePatternType.MultiOcr: return new OcrFinder(patternInfo); case ePatternType.Brightness: return new Brightness(patternInfo); case ePatternType.LineIntersection: return new LineIntersection(patternInfo); case ePatternType.LineWidth: return new LineWidth(patternInfo); case ePatternType.MachinePattern_A: case ePatternType.MachinePattern_B: case ePatternType.MachinePattern_C: return EquipAdapter.Instance.MachinePatternManager.GetPattern(patternInfo); } _logger.E($"No matching of PatternType : {patternInfo.PatternType}"); return null; } public override List GetPatternInfoListFromFiles(string curRecipePath) { var patternInfoList = new List(); var camRecipe = VisionRecipeManager.GetCamRecipe(_fovInfo); var patternCount = 0; if (VisionSettingManager.VisionSetting.UseCamPattern) { patternCount = PatternConstants.CAM_PATTERN_COUNT; } else { patternCount = PatternConstants.FOV_PATTERN_COUNT; } for (int patternId = 0; patternId < patternCount; patternId++) { string patternDirPath; if (VisionSettingManager.VisionSetting.UseCamPattern) { patternDirPath = Path.Combine( curRecipePath, PatternConstants.DIR_NAME_PATTERN, ((int)_camId).ToString(), patternId.ToString()); } else { patternDirPath = Path.Combine( curRecipePath, PatternConstants.DIR_NAME_PATTERN, ((int)_fovInfo.UnitId).ToString(), ((int)_fovInfo.SubSysId).ToString(), ((int)_fovInfo.FovId).ToString(), patternId.ToString()); } if (Directory.Exists(patternDirPath)) { var patternDirPathList = Directory.GetDirectories(patternDirPath, "??", SearchOption.TopDirectoryOnly); foreach (var subPatternDirPath in patternDirPathList) { if (Directory.Exists(subPatternDirPath)) { var patternInfoFilePath = Path.Combine(subPatternDirPath, PatternConstants.FILE_NAME_PATTERN_INFO); if (File.Exists(patternInfoFilePath)) { var patternInfo = LoadPatternInfoFromFile(patternInfoFilePath); patternInfo.MilSystemId = GetMilSystemId(camRecipe.CamId); patternInfo.PatternIndex = new PatternIndex( _fovInfo.UnitId, _fovInfo.SubSysId, _fovInfo.FovName, _fovInfo.FovId, patternId, Convert.ToInt32(Path.GetFileName(subPatternDirPath))); patternInfoList.Add(patternInfo); } } } } } return patternInfoList; } private PatternInfo LoadPatternInfoFromFile(string filePath) { return JsonConvert.DeserializeObject( File.ReadAllText(filePath), typeof(PatternInfo)) as PatternInfo; } public override int GetMilSystemId(eCamId camId) { var camConfig = VisionEnv.AuroraEnv.DeviceManager.GetDeviceConfig(camId.ToString()) as CamConfig; if (camConfig != null) { return (int)MilEnvironment.Instance.GetSystem(camConfig.CamConnConfig.BoardType, camConfig.CamConnConfig.BoardSlotPos); } else { return 0; } } private Dictionary SortDictionary(Dictionary dict) { return dict.OrderBy(item => item.Key).ToDictionary(x => x.Key, x => x.Value); } public override int GetFindNumber(PatternInfo patternInfo) { if (patternInfo.PatternType == ePatternType.ImageModelFinder) { ImageModelFinder imageModelFinder = new ImageModelFinder(patternInfo); return (imageModelFinder.GetFindNumber()); } else if (patternInfo.PatternType == ePatternType.ShapeModelFinder) { ShapeModelFinder shapeModelFinder = new ShapeModelFinder(patternInfo); return (shapeModelFinder.GetFindNumber()); } else if (patternInfo.PatternType == ePatternType.PatternMatching) { PatternMatching patternMatching = new PatternMatching(patternInfo); return (patternMatching.GetFindNumber()); } else { return 1; } } public override bool IsTrainPattern(PatternInfo patternInfo) { var pattern = GetPattern(patternInfo); if (pattern is IPatternTrain) { return true; } else { return false; } } public override bool IsDeletable(PatternInfo patternInfo, int patternIndex) { if (patternInfo.PatternType == ePatternType.LineIntersection) { var runparam = GetRunParam(patternInfo) as LineIntersectionRunParam; if (runparam.PatternId1 == patternIndex || runparam.PatternId2 == patternIndex) { return false; } } else if (patternInfo.PatternType == ePatternType.LineWidth) { var runparam = GetRunParam(patternInfo) as LineWidthRunParam; if (runparam.PatternId1 == patternIndex || runparam.PatternId2 == patternIndex) { return false; } } return true; } } }