2026-01-26 18:56:53 +09:00

513 lines
22 KiB
C#

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 {
/// <summary>
/// MIL 패턴 에이전트
/// </summary>
public MilPatternAgent(
FovInfo fovInfo) : base(fovInfo) {
LoadPatterns();
SetObservable();
}
private void SetObservable() {
var observable = VisionEventId.GetRecipeActivatedObservable();
observable.Subscribe(_ => LoadPatterns());
}
public override Dictionary<PatternInfo, IPatternFinder> GetPatterns() {
return _patterns;
}
#region Main Patterns
public override List<PatternInfo> GetMainPatterns(SubSysInfo subSysInfo, eFovId fovId) {
var fovIdxPrefix = PatternIndex.GetPrefix(subSysInfo.UnitId, subSysInfo.SubSysId, fovId);
return GetMainPatterns(fovIdxPrefix);
}
public override List<PatternInfo> 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();
}
}
/// <summary>
/// 패턴 가져오기
/// </summary>
/// <returns>패턴</returns>
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<PatternResult>();
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<PatternInfo> GetPatternInfoListFromFiles(string curRecipePath) {
var patternInfoList = new List<PatternInfo>();
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<T, U> SortDictionary<T, U>(Dictionary<T, U> 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;
}
}
}