/* * Copyright (c) 2025 LG Electronics Inc. * SPDX-License-Identifier: LicenseRef-LGE-Proprietary */ using Aurora.Api; using Aurora.View; using VisionCommon; using Cognex.VisionPro; using CogPattern; using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Linq; using System.Windows; using System.Windows.Input; using System.Windows.Media; using VisionCommonUI; using VisionCommonUI.Resources; using CogCommon; using Aurora.Api.DataType; using Cognex.VisionPro.ImageProcessing; namespace CogUI { public class TrainOriginSyncViewModel : NotifyPropertyChangedBase { private Logger _logger = new Logger("TrainOriginSyncVM"); public ICommand CMD_Clear { get; } public ICommand CMD_Find { get; } public ICommand CMD_SyncXY { get; } public ICommand CMD_SyncT { get; } public ICommand CMD_Cancel { get; } private bool _enableSyncT; public bool EnableSyncT { get => _enableSyncT; set => SetProperty(ref _enableSyncT, value); } public ObservableCollection TrainOriginInfos { get; set; } private int _selectedPatternIndex; public int SelectedPatternIndex { get => _selectedPatternIndex; set { _selectedPatternIndex = value; CalcOriginOffset(value); } } private PatternAgentBase _patternAgent; private PatternInfo _patternInfo; private CameraDisplay _cameraDisplay; public TrainOriginSyncViewModel( PatternAgentBase patternAgent, PatternInfo patternInfo, ICameraDisplay cameraDisplay) { _patternAgent = patternAgent; _patternInfo = patternInfo; _cameraDisplay = cameraDisplay as CameraDisplay; CMD_Clear = new DelegateCommand(Clear); CMD_Find = new DelegateCommand(Find); CMD_SyncXY = new DelegateCommand(SyncXY); CMD_SyncT = new DelegateCommand(SyncT); CMD_Cancel = new DelegateCommand(Cancel); SetEnableSyncT(); InitTrainOriginInfos(0); } public void SetEnableSyncT() { EnableSyncT = _patternInfo.PatternType == ePatternType.ImageModelFinder; } public void InitTrainOriginInfos(int initIndex) { try { Application.Current.Dispatcher.Invoke( new Action(() => { if (TrainOriginInfos == null) { TrainOriginInfos = new ObservableCollection(); } TrainOriginInfos.Clear(); var existingPatternInfos = _patternAgent.GetMainSubPatterns(_patternInfo); foreach (var patternInfo in existingPatternInfos) { var trainOriginInfo = new TrainOriginInfo( patternInfo, GetSolidColorBrush(patternInfo.GetPatternSubId())); TrainOriginInfos.Add(trainOriginInfo); } SelectedPatternIndex = initIndex; })); } catch (Exception e) { _logger.FuncE(e.Message); } } private void CalcOriginOffset(int selectedIndex) { if (TrainOriginInfos.Count <= selectedIndex) { _logger.FuncE($"TrainOriginInfos does not contain the index [{selectedIndex}]."); return; } if (0 < TrainOriginInfos.Count && 0 <= selectedIndex) { var newTrainOriginInfos = new ObservableCollection(); var origin = TrainOriginInfos[selectedIndex].OriginPoint.Clone() as ImagePoint; var t = TrainOriginInfos[selectedIndex].T.Clone() as Angle; foreach (var trainOriginInfo in TrainOriginInfos) { var toi = trainOriginInfo.Clone(); toi.OriginOffset = origin - trainOriginInfo.OriginPoint as ImagePoint; toi.TOffset = t - trainOriginInfo.T; newTrainOriginInfos.Add(toi); } TrainOriginInfos = newTrainOriginInfos; NotifyPropertyChanged("TrainOriginInfos"); _selectedPatternIndex = selectedIndex; NotifyPropertyChanged("SelectedPatternIndex"); } } private void Clear(object obj) { _cameraDisplay.ClearMeasureGraphics(); InitTrainOriginInfos(0); } private void Find(object obj) { _cameraDisplay.ClearMeasureGraphics(); var lastSelectedPatternIndex = _selectedPatternIndex; var newTrainOriginInfos = new ObservableCollection(); var notFoundPatternSubIds = new List(); var patternInfos = _patternAgent.GetMainSubPatterns(_patternInfo); foreach (var patternInfo in patternInfos) { var runParam = _patternAgent.GetRunParam(patternInfo); _patternAgent.SetRunParam(patternInfo, runParam); var patternResult = _patternAgent.Find(patternInfo, _cameraDisplay.GetImage()); if (patternResult.Status != eFoundStatus.NotFound) { var result = patternResult.Results.ToList()[0]; _cameraDisplay.AddCross( new Cross(result.ImagePosition.Clone() as ImagePoint, result.Angle, 50), GetDrawingColor(patternInfo.GetPatternSubId())); newTrainOriginInfos.Add( new TrainOriginInfo(patternInfo, GetSolidColorBrush(patternInfo.GetPatternSubId())) { OriginPoint = result.ImagePosition, T = result.Angle.Clone() as Angle }); } else { notFoundPatternSubIds.Add(patternInfo.GetPatternSubId()); } } TrainOriginInfos = newTrainOriginInfos; CalcOriginOffset(lastSelectedPatternIndex); if (0 < notFoundPatternSubIds.Count) { string strIds = string.Empty; for (int i = 0; i < notFoundPatternSubIds.Count; i++) { strIds += notFoundPatternSubIds[i].ToString(); if (i != notFoundPatternSubIds.Count - 1) { strIds += ", "; } } MessageBoxUtil.ShowMessageBoxWarning( string.Format(StrTokens.MSG_W_PatternNotFoundFormat, strIds)); } } private void SyncXY(object obj) { var result = MessageBoxUtil.ShowMessageBoxQuestion( string.Format(StrTokens.MSG_Q_SyncPatternOriginFormat, SelectedPatternIndex)); if (result == MessageBoxResult.Yes) { foreach (var trainOriginInfo in TrainOriginInfos) { if (trainOriginInfo.PaternInfo == TrainOriginInfos[SelectedPatternIndex].PaternInfo) { continue; } var patternTrain = _patternAgent.GetPattern(trainOriginInfo.PaternInfo) as IPatternTrain; var trainParam = patternTrain.GetTrainParam() as ImageTrainParam; var newTrainOrigin = new Cross(new ImagePoint( Math.Round(trainParam.TrainOrigin.Origin.X + trainOriginInfo.OriginOffset.X, 1), Math.Round(trainParam.TrainOrigin.Origin.Y + trainOriginInfo.OriginOffset.Y, 1))); _logger.I($"oldTrainOrigin : {trainParam.TrainOrigin}, offset : {trainOriginInfo.OriginOffset}"); _logger.I($"newTrainOrigin : {newTrainOrigin.Origin}"); ((IPatternMask)patternTrain).SetTrainOrigin(newTrainOrigin); ((IPatternFinder)patternTrain).Save(); } MessageBoxUtil.ShowMessageBoxOk(StrTokens.MSG_O_SaveCompleted); } } private void SyncT(object obj) { var result = MessageBoxUtil.ShowMessageBoxQuestion( string.Format(StrTokens.MSG_Q_SyncPatternOriginFormat, SelectedPatternIndex)); if (result == MessageBoxResult.Yes) { foreach (var trainOriginInfo in TrainOriginInfos) { if (trainOriginInfo.PaternInfo == TrainOriginInfos[SelectedPatternIndex].PaternInfo) { continue; } var pattern = _patternAgent.GetPattern(trainOriginInfo.PaternInfo); var patternTrain = pattern as IPatternTrain; var patternMask = pattern as IPatternMask; var trainParam = patternTrain.GetTrainParam() as ImageTrainParam; var runParam = pattern.GetRunParam() as ModelFinderRunParam; var modelImage = patternMask.GetModelImage(); var maskImage = patternMask.GetMaskImage(); // 수정 필요... // Rotation //CogIPOneImageTool cogIPOneImageTool = new CogIPOneImageTool(); //var imgFlipRotate = new CogIPOneImageFlipRotate(); //imgFlipRotate.Enabled = true; //imgFlipRotate.OperationInPixelSpace = CogIPOneImageFlipRotateOperationConstants.Rotate90Deg; //cogIPOneImageTool.Operators.Add(imgFlipRotate); //cogIPOneImageTool.InputImage = maskImage; //cogIPOneImageTool.Run(); //var bitmap = cogIPOneImageTool.OutputImage.ToBitmap(); //maskImage = new CogImage8Grey(bitmap); //bitmap.Dispose(); // //MIL.MimRotate( // maskImage, maskImage, trainOriginInfo.TOffset.Degree * -1, // trainParam.TrainOriginInModel.X, trainParam.TrainOriginInModel.Y, // trainParam.TrainOriginInModel.X, trainParam.TrainOriginInModel.Y, // MIL.M_NEAREST_NEIGHBOR); //var trainImageSize = new ImageSize() { // Width = (int)(trainParam.TrainRoi.Right + 100), // Height = (int)(trainParam.TrainRoi.Bottom + 100), // Channel = 1, // BitDepth = 8 //}; //var trainImage = CogEnvironment.GetCompatibleGrayImageBuffer( // trainImageSize, CogEnvironment.GetSystemOfBuffer(maskImage)); //MIL.MbufCopyClip(modelImage, trainImage, (int)trainParam.TrainRoi.Left, (int)trainParam.TrainRoi.Top); //trainParam.TrainImage = trainImage; trainParam.TrainRoi.Angle += Angle.CreateWithDegree(trainOriginInfo.TOffset.Degree); patternTrain.Train(trainParam); //patternMask.SetMaskImage(maskImage); pattern.SetRunParam(runParam); pattern.Save(); //CogEnvironment.FreeImage(modelImage); //CogEnvironment.FreeImage(maskImage); //CogEnvironment.FreeImage(trainImage); } MessageBoxUtil.ShowMessageBoxOk(StrTokens.MSG_O_SaveCompleted); } } private SolidColorBrush GetSolidColorBrush(int patternSubId) { switch (patternSubId) { case 0: return new SolidColorBrush(Color.FromRgb(0, 0xFF, 0xFF)); // Cyan case 1: return new SolidColorBrush(Color.FromRgb(0xFF, 0, 0xFF)); // Magenta case 2: return new SolidColorBrush(Color.FromRgb(0xFF, 0x5F, 0x1F)); // Neon Orange case 3: return new SolidColorBrush(Color.FromRgb(0xFF, 0xFF, 0)); // Yellow case 4: default: return new SolidColorBrush(Color.FromRgb(0, 0xFF, 0)); // Green } } private CogColorConstants GetDrawingColor(int patternSubId) { switch (patternSubId) { case 0: return CogColorConstants.Cyan; case 1: return CogColorConstants.Magenta; case 2: return CogColorConstants.Orange; case 3: return CogColorConstants.Yellow; case 4: default: return CogColorConstants.Green; } } private void Cancel(object obj) { CloseWindow(obj); } private void CloseWindow(object obj) { var window = obj as Window; if (window != null) { window.Close(); } } } }