2026-06-05 13:44:39 +09:00

1535 lines
76 KiB
C#

using Aurora.View;
using System;
using System.Collections.Generic;
using System.Windows.Input;
using OpenCvSharp;
using System.Linq;
using OpenCvSharp.WpfExtensions;
using System.Windows.Media.Imaging;
using System.Windows.Forms;
using Matrox.MatroxImagingLibrary;
using Aurora.Api;
using Aurora.Api.Control;
using MilCommon;
using VisionCommon;
using System.IO;
using System.Diagnostics;
using System.Configuration;
using CoreUnit.Control.UserControl.Canvas;
//using System.Windows.Shapes;
using Aurora;
using Point = OpenCvSharp.Point;
using Rect = OpenCvSharp.Rect;
using Size = OpenCvSharp.Size;
using System.Collections.ObjectModel;
using CoreUnit.Scanner.UserControl.ScannerCanvas;
using System.Reactive.Linq;
using Application = System.Windows.Application;
using WeldingCommon.Sequences;
using WeldingCommon.Vision.WeldingObjectGenerator.PathEditorLibrary;
using WeldingCommon;
using WeldingCommon.Vision.WeldingObjectGenerator;
using WeldingCommon.Utils;
using WeldingCommon.Data;
using System.Reactive.Concurrency;
using System.Text.RegularExpressions;
using WeldingCommon.Settings;
using OpenCvSharp.Flann;
using static CoreUnit.Control.UserControl.Canvas.ZigZag;
using System.ComponentModel;
namespace WeldingCommon.Views
{
public class UCConvEdgeObjectViewModel : NotifyPropertyChangedBase
{
private readonly Logger Log = new Logger("ConvEdgeObject");
private readonly IAuroraEnvironment _auroraEnv;
public ObservableCollection<string> Options { get; set; }
public ObservableCollection<ButtonViewModel> CurrentButtons { get; set; }
public string _selectedOption;
public string SelectedOption {
get { return _selectedOption; }
set {
_selectedOption = value;
OnPropertyChanged(nameof(SelectedOption));
UpdateButtons();
}
}
#region Binding Property
private BitmapSource _OriginImage;
public BitmapSource OriginImage { get => _OriginImage; set => SetProperty(ref _OriginImage, value); }
private BitmapSource _MaskedImage;
public BitmapSource MaskedImage { get => _MaskedImage; set => SetProperty(ref _MaskedImage, value); }
private BitmapSource _ResultImage;
public BitmapSource ResultImage { get => _ResultImage; set => SetProperty(ref _ResultImage, value); }
private double _CVThreshold;
public double CVThreshold { get => _CVThreshold; set => SetProperty(ref _CVThreshold, value); }
private int _CVShrinkPixel;
public int CVShrinkPixel { get => _CVShrinkPixel; set => SetProperty(ref _CVShrinkPixel, value); }
private int _CVShrinkPixel2;
public int CVShrinkPixel2 { get => _CVShrinkPixel2; set => SetProperty(ref _CVShrinkPixel2, value); }
private int _CVShrinkPixel3;
public int CVShrinkPixel3 { get => _CVShrinkPixel3; set => SetProperty(ref _CVShrinkPixel3, value); }
private int _CVShrinkPixel4;
public int CVShrinkPixel4 { get => _CVShrinkPixel4; set => SetProperty(ref _CVShrinkPixel4, value); }
private double _Radius;
public double Radius { get => _Radius; set => SetProperty(ref _Radius, value); }
private int _Margin;
public int Margin { get => _Margin; set => SetProperty(ref _Margin, value); }
private int _PointNum;
public int PointNum { get => _PointNum; set => SetProperty(ref _PointNum, value); }
private double _DetectPointPercent;
public double DetectPointPercent { get => _DetectPointPercent; set => SetProperty(ref _DetectPointPercent, value); }
private int _CVMorpIterations;
public int CVMorpIterations { get => _CVMorpIterations; set => SetProperty(ref _CVMorpIterations, value); }
private int _CVMorpMaskSize;
public int CVMorpMaskSize { get => _CVMorpMaskSize; set => SetProperty(ref _CVMorpMaskSize, value); }
private double _MILThreshold;
public double MILThreshold { get => _MILThreshold; set => SetProperty(ref _MILThreshold, value); }
private double _MILFillGapDist;
public double MILFillGapDist { get => _MILFillGapDist; set => SetProperty(ref _MILFillGapDist, value); }
private double _MILShrinkDist;
public double MILShrinkDist { get => _MILShrinkDist; set => SetProperty(ref _MILShrinkDist, value); }
private double _CVInnerCircleSize;
public double CVInnerCircleSize { get => _CVInnerCircleSize; set => SetProperty(ref _CVInnerCircleSize, value); }
private double _CVOuterCircleSize;
public double CVOuterCircleSize { get => _CVOuterCircleSize; set => SetProperty(ref _CVOuterCircleSize, value); }
private double _DrawObjectDistanceRange;
public double DrawObjectDistanceRange { get => _DrawObjectDistanceRange; set => SetProperty(ref _DrawObjectDistanceRange, value); }
private double _DrawObjectLengthSumDiffRange;
public double DrawObjectLengthSumDiffRange { get => _DrawObjectLengthSumDiffRange; set => SetProperty(ref _DrawObjectLengthSumDiffRange, value); }
private double _DrawObjectDistanceMin;
public double DrawObjectDistanceMin { get => _DrawObjectDistanceMin; set => SetProperty(ref _DrawObjectDistanceMin, value); }
private double _DrawObjectDistanceMax;
public double DrawObjectDistanceMax { get => _DrawObjectDistanceMax; set => SetProperty(ref _DrawObjectDistanceMax, value); }
private double _DrawObjectArcLengthMax;
public double DrawObjectArcLengthMax { get => _DrawObjectArcLengthMax; set => SetProperty(ref _DrawObjectArcLengthMax, value); }
private double _DrawObjectCenterXYDiffRange;
public double DrawObjectCenterXYDiffRange { get => _DrawObjectCenterXYDiffRange; set => SetProperty(ref _DrawObjectCenterXYDiffRange, value); }
private double _MergeDist;
public double MergeDist { get => _MergeDist; set => SetProperty(ref _MergeDist, value); }
private uint _MaxArcRadius;
public uint MaxArcRadius { get => _MaxArcRadius; set => SetProperty(ref _MaxArcRadius, value); }
private uint _LineTolerance;
public uint LineTolerance { get => _LineTolerance; set => SetProperty(ref _LineTolerance, value); }
private uint _ArcTolerance;
public uint ArcTolerance { get => _ArcTolerance; set => SetProperty(ref _ArcTolerance, value); }
private float _LineDefualtWidth;
public float LineDefualtWidth { get => _LineDefualtWidth; set => SetProperty(ref _LineDefualtWidth, value); }
private int _ObjectNumber;
public int ObjectNumber { get => _ObjectNumber; set => SetProperty(ref _ObjectNumber, value); }
private ObservableCollection<ContourList> _ContourCorrection = new ObservableCollection<ContourList>();
public ObservableCollection<ContourList> ContourCorrection { get => _ContourCorrection; set => SetProperty(ref _ContourCorrection, value); }
private double _ReferenceX;
public double ReferenceX { get => _ReferenceX; set => SetProperty(ref _ReferenceX, value); }
private double _ReferenceY;
public double ReferenceY { get => _ReferenceY; set => SetProperty(ref _ReferenceY, value); }
private double _ReferenceTh;
public double ReferenceTh { get => _ReferenceTh; set => SetProperty(ref _ReferenceTh, value); }
private double _OffsetX;
public double OffsetX { get => _OffsetX; set => SetProperty(ref _OffsetX, value); }
private double _OffsetY;
public double OffsetY { get => _OffsetY; set => SetProperty(ref _OffsetY, value); }
private double _OffsetTh;
public double OffsetTh { get => _OffsetTh; set => SetProperty(ref _OffsetTh, value); }
public ICommand CMD_LoadImage { get; }
public ICommand CMD_CheckRadiusImage { get; }
public ICommand CMD_DetectImage { get; }
public ICommand CMD_SaveImage { get; }
public ICommand CMD_SaveCSV { get; }
public ICommand CMD_GenerateDrawingObject { get; }
public ICommand CMD_VisionTypeChanged { get; }
public ICommand CMD_OffsetTypeChanged { get; }
public ICommand CMD_ObjectGenTypeChanged { get; }
public ICommand CMD_CenterDetectTest { get; }
public ICommand CMD_RecommendDetectParam { get; }
public ICommand CMD_RecipeUpdate { get; }
public ICommand CMD_OffsetUpdate { get; }
public ICommand CMD_OffsetSave { get; }
public ICommand CMD_FindReference { get; }
public ICommand CMD_FindObject { get; }
public ICommand CMD_RecipeUpdateObject { get; }
// Flying vision + Detect Image + Generate Object + Welding Sequence
public ICommand CMD_FlyingSeqStart { get; }
public ICommand CMD_FlyingSeqRun { get; }
public ICommand CMD_FlyingSeqStop { get; }
public ICommand CMD_SystemParamSave { get; }
#endregion
private readonly ISequenceEntry _SequenceEntry;
private readonly IEventObservable _EventObservable = Application.Current.AuroraEnv().EventObservable;
private ISequence _ManualRunRCC;
private ISequence _AutoRunSMWSeq_wo_Scout;
private ISequence _AutoRunSMWSeq_Scout;
#region MIL Property
MIL_ID Edge_Contour_Context = MIL.M_NULL;
MIL_ID Edge_Result = MIL.M_NULL;
MIL_ID MedgeCalculate_graphicContext = MIL.M_NULL;
MIL_ID MedgeCalculate_graphicList = MIL.M_NULL;
MIL_ID MILGrayImage = MIL.M_NULL;
MIL_ID MilBinaryImage = MIL.M_NULL;
MIL_ID MILImage = MIL.M_NULL;
#endregion
private Mat _LoadImageMat;
private Mat _DetectImageMat;
private Mat _ConvImageMat;
private Mat _MaskedImageMat;
private ObjectGenerator _ObjGenerator;
private CameraAgentBase _CameraAgent;
private Stopwatch _Stopwatch;
private string _ImagePath;
private string _VisionType = "OpenCV";
private string _OffsetType = "Manual";
private string _ObjectGenType = "Auto";
private Point _CenterPoint;
private Point[][] _MaxContour;
private double[] _XCoordinates;
private double[] _YCoordinates;
private Point[][] _EdgePoints;
private List<IDrawObject> _DestDrawObjectList;
private double _Offset_x, _Offset_y, _Offset_t;
private int _Ref_x, _Ref_y;
private double _Ref_t;
private List<PathItem> _PathList;
private WeldingCommon.Settings.SystemParameter _SystemParam;
private ISettingEntry _SettingEntry;
private static ScannerCanvasUserCtrl _ScannerCanvasUserCtrl;
private double _CenterX;
private double _CenterY;
private double _ImageWidth;
private double _ImageHeight;
private UnitPoint _Obejct_Center;
private Point[][] _MinContour;
private double _PixelResolution;
private SequenceDialog _SequenceDialog;
private Arc.eDirection _Draw_direction;
public UCConvEdgeObjectViewModel(IAuroraEnvironment aurora)
{
Options = new ObservableCollection<string> { "SMW", "Inzi", "LFW" };
CurrentButtons = new ObservableCollection<ButtonViewModel>();
SelectedOption = Options[0];
CMD_LoadImage = new DelegateCommand(PerformCmdLoadImage);
CMD_CheckRadiusImage = new DelegateCommand(PerformCmdCheckRadiusImage);
CMD_DetectImage = new DelegateCommand(PerformCmdDetectImage);
CMD_SaveImage = new DelegateCommand(PerformCmdSaveImage);
CMD_SaveCSV = new DelegateCommand(PerformCmdSaveCSV);
CMD_GenerateDrawingObject = new DelegateCommand(PerformCmdGenerateDrawingObject);
CMD_VisionTypeChanged = new DelegateCommand(PerformCmdVisionTypeChanged);
CMD_OffsetTypeChanged = new DelegateCommand(PerformCmdOffsetTypeChanged);
CMD_ObjectGenTypeChanged = new DelegateCommand(PerformCmdObjectGenTypeChanged);
CMD_CenterDetectTest = new DelegateCommand(PerformCmdCenterDetectTest);
CMD_RecommendDetectParam = new DelegateCommand(PerformCmdRecommendDetectParam);
CMD_RecipeUpdate = new DelegateCommand(PerformCmdRecipeUpdate);
CMD_OffsetUpdate = new DelegateCommand(PerformCmdOffsetUpdate);
CMD_OffsetSave = new DelegateCommand(PerformCmdOffsetSave);
CMD_FindReference = new DelegateCommand(PerformCmdFindReference);
CMD_FindObject = new DelegateCommand(PerformCmdFindObject);
CMD_RecipeUpdateObject = new DelegateCommand(PerformCmdRecipeUpdateObject);
CMD_FlyingSeqStart = new DelegateCommand(PerformCmdFlyingSeqStart);
CMD_FlyingSeqRun = new DelegateCommand(PerformCmdFlyingSeqRun);
CMD_FlyingSeqStop = new DelegateCommand(PerformCmdFlyingSeqStop);
CMD_SystemParamSave = new DelegateCommand(PerformCmdSystemParameterSave);
_auroraEnv = aurora;
_SequenceEntry = _auroraEnv.SequenceEntry;
_ManualRunRCC = _SequenceEntry[CommonSequenceIds.SeqManualRunRCC];
_EventObservable.AsObservable(CommonSequenceIds.SeqManualRunRCC)
.ObserveOn(Application.Current.Dispatcher)
.Subscribe(OnUpdateManualRunResult);
var fovInfo = VisionRecipeManager.GetFovInfos().FirstOrDefault();
_CameraAgent = CameraAgentManager.GetCameraAgent(fovInfo);
_SystemParam = aurora.SettingEntry[CommonSettingIds.SystemParameter] as WeldingCommon.Settings.SystemParameter;
_SettingEntry = aurora.SettingEntry;
_Stopwatch = new Stopwatch();
_PixelResolution = ((_SystemParam.CameraPixelSize) / _SystemParam.LensMagnification) / 1000.0;
_ObjGenerator = new ObjectGenerator(0, 0, _PixelResolution);
if (_SystemParam.OffsetType == eOffsetType.manual) {
_ObjGenerator.SetOffsetType("Manual");
} else {
_ObjGenerator.SetOffsetType("CSV");
}
if (_SystemParam.OffsetCSVFile != null) {
_ObjGenerator.setOffsetTable(_SystemParam.OffsetCSVFile, _SystemParam.LensMagnification, _SystemParam.CameraPixelSize);
} else {
Log.W("Not exist CSV OffsetTable of Systemparameter");
}
UpdateButtons();
#region Initialize Property
CVThreshold = _SystemParam.CVThreshold;
CVMorpIterations = _SystemParam.CVMorpIterations;
CVMorpMaskSize = _SystemParam.CVMorpMaskSize;
CVShrinkPixel = _SystemParam.CVShrinkPixel;
CVShrinkPixel2 = _SystemParam.CVShrinkPixel2;
CVShrinkPixel3 = _SystemParam.CVShrinkPixel3;
CVShrinkPixel4 = _SystemParam.CVShrinkPixel4;
Radius = _SystemParam.Radius;
Margin = _SystemParam.Margin;
PointNum = _SystemParam.PointNum;
DetectPointPercent = _SystemParam.DetectPointPercent; // %
MILThreshold = 10;
MILFillGapDist = 20;
MILShrinkDist = 40;
CVInnerCircleSize = _SystemParam.CVInnerCircleSize; // mm
CVOuterCircleSize = _SystemParam.CVOuterCircleSize; // mm
MergeDist = _SystemParam.dMergeDist;
MaxArcRadius = _SystemParam.nMaxArcRadius;
LineTolerance = _SystemParam.nLineTolerance;
ArcTolerance = _SystemParam.nArcTolerance;
LineDefualtWidth = _SystemParam.fLineDefualtWidth;
ObjectNumber = _SystemParam.ObjectNumber;
DrawObjectDistanceMin = _SystemParam.DrawObjectDistanceMin; // mm
DrawObjectDistanceMax = _SystemParam.DrawObjectDistanceMax; // mm
DrawObjectDistanceRange = _SystemParam.DrawObjectDistanceRange; // mm
DrawObjectLengthSumDiffRange = _SystemParam.DrawObjectLengthSumDiffRange; // mm
DrawObjectArcLengthMax = _SystemParam.DrawObjectArcLengthMax; // mm
DrawObjectCenterXYDiffRange = _SystemParam.DrawObjectCenterXYDiffRange;
#endregion
}
private void UpdateButtons()
{
CurrentButtons.Clear();
if (SelectedOption == "SMW") {
CurrentButtons.Add(new ButtonViewModel("Check Radius", CMD_CheckRadiusImage));
CurrentButtons.Add(new ButtonViewModel("Edge Detect", CMD_DetectImage));
CurrentButtons.Add(new ButtonViewModel("Generate Object", CMD_GenerateDrawingObject));
CurrentButtons.Add(new ButtonViewModel("Recipe Update", CMD_RecipeUpdate));
CurrentButtons.Add(new ButtonViewModel("Save Offset Table", CMD_OffsetSave));
CurrentButtons.Add(new ButtonViewModel("Update Offset Table", CMD_OffsetUpdate));
} else if (SelectedOption == "Inzi") {
CurrentButtons.Add(new ButtonViewModel("Find Reference", CMD_FindReference));
CurrentButtons.Add(new ButtonViewModel("Find Offset", CMD_FindObject));
CurrentButtons.Add(new ButtonViewModel("Recipe Update", CMD_RecipeUpdateObject));
} else if (SelectedOption == "LFW") {
CurrentButtons.Add(new ButtonViewModel("Find Reference", CMD_FindReference));
CurrentButtons.Add(new ButtonViewModel("Find Offset", CMD_FindObject));
CurrentButtons.Add(new ButtonViewModel("Recipe Update", CMD_RecipeUpdateObject));
}
CommandManager.InvalidateRequerySuggested();
}
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged(string propertyName)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
private void PerformCmdSystemParameterSave(object obj)
{
var result = MessageDialog.Show(Application.Current.MainWindow, "RCC", $"Save RCC parameters in system parameters??",
MessageDialog.Type.AffirmativeAndNegative);
if (result == MessageDialog.Result.Negative) {
return;
}
_SystemParam.CVThreshold = CVThreshold;
_SystemParam.CVShrinkPixel = CVShrinkPixel;
_SystemParam.CVShrinkPixel2 = CVShrinkPixel2;
_SystemParam.CVShrinkPixel3 = CVShrinkPixel3;
_SystemParam.CVShrinkPixel4 = CVShrinkPixel4;
_SystemParam.Margin = Margin; // mm
_SystemParam.Radius = Radius; // mm
_SystemParam.PointNum = PointNum; // divide count
_SystemParam.DetectPointPercent = DetectPointPercent; // %
_SystemParam.dMergeDist = MergeDist;
_SystemParam.nMaxArcRadius = MaxArcRadius;
_SystemParam.nLineTolerance = LineTolerance;
_SystemParam.nArcTolerance = ArcTolerance;
_SystemParam.fLineDefualtWidth = LineDefualtWidth;
_SystemParam.ObjectNumber = ObjectNumber;
_SystemParam.DrawObjectDistanceMin = DrawObjectDistanceMin; // mm
_SystemParam.DrawObjectDistanceMax = DrawObjectDistanceMax; // mm
_SystemParam.DrawObjectDistanceRange = DrawObjectDistanceRange; // mm
_SystemParam.DrawObjectLengthSumDiffRange = DrawObjectLengthSumDiffRange; // mm
_SystemParam.DrawObjectArcLengthMax = DrawObjectArcLengthMax; // mm
_SystemParam.DrawObjectCenterXYDiffRange = DrawObjectCenterXYDiffRange; //mm
_SystemParam.ReferenceX = _Ref_x; //mm
_SystemParam.ReferenceY = _Ref_y; //mm
_SystemParam.ReferenceTh = _Ref_t; //deg
_SettingEntry.Save(CommonSettingIds.SystemParameter, _SystemParam, "RCC");
}
private void PerformCmdVisionTypeChanged(object obj)
{
_VisionType = (string)obj;
}
private void PerformCmdOffsetTypeChanged(object obj)
{
_OffsetType = (string)obj;
_ObjGenerator.SetOffsetType(_OffsetType);
}
private void PerformCmdObjectGenTypeChanged(object obj)
{
_ObjectGenType = (string)obj;
_ObjGenerator.SetOffsetType(_ObjectGenType);
}
private void PerformCmdSaveImage(object obj)
{
SaveFileDialog sfd = new SaveFileDialog();
sfd.Filter = "JPEG Image|*.jpg|PNG Image|*.png|Bitmap Image|*.bmp";
sfd.Title = "Save an Image File";
sfd.DefaultExt = "jpg"; // 기본 확장자를 설정합니다.
sfd.FileName = string.Format($"ResultImage_{DateTime.Now.Month}_{DateTime.Now.Day}_{DateTime.Now.ToString("HHmmss")}.jpg"); // 기본 파일 이름을 설정합니다.
DialogResult dr = sfd.ShowDialog();
if (dr == DialogResult.OK) {
string savepath = sfd.FileName;
//bitmapSource를 이미지 파일로 저장
BitmapEncoder encoder = new JpegBitmapEncoder();
using (FileStream stream = new FileStream(savepath, FileMode.Create)) {
encoder.Frames.Add(BitmapFrame.Create(ResultImage));
encoder.Save(stream);
}
}
}
private void PerformCmdSaveCSV(object obj)
{
if (_MaxContour != null) {
SaveContoursToCsv(_MaxContour);
}
//Jin : 미사용
//switch (_VisionType) {
// case "OpenCV":
// if (_MaxContour != null) {
// SaveContoursToCsv(_MaxContour);
// } else {
// SaveCenterToCsv(_CenterX, _CenterY);
// }
// break;
// case "MIL":
// SaveCoordinatesToCsv(_XCoordinates, _YCoordinates);
// break;
//}
}
private void PerformCmdGenerateDrawingObject(object obj)
{
GenerateDrawingObject();
}
private void GenerateDrawingObject()
{
_ObjGenerator.SetInterlockProperties(DrawObjectDistanceRange, DrawObjectArcLengthMax, DrawObjectLengthSumDiffRange, DrawObjectCenterXYDiffRange);
if (!GetArcInfoFromRecipe()) {
return;
}
// MaxContour가 0일 경우 예외처리
if (_MaxContour[0].Count() < 1) {
Log.E("MaxContour is Null");
return;
}
// maxContour 를 보내자
if (_VisionType == "OpenCV") {
_ObjGenerator.SetPolygonFromList(_MaxContour);
} else {
_ObjGenerator.SetPolygonFromList(_EdgePoints);
}
if (_ObjectGenType == "ArcByAngle")
_ObjGenerator.CalculateAutoPathAngle(ObjectNumber);
else
_ObjGenerator.CalculateAutoPath(_MergeDist, _MaxArcRadius, _LineTolerance, _ArcTolerance);
_ObjGenerator.ConvertPathItemToDrawingObjects(LineDefualtWidth, out _DestDrawObjectList);
if (_ObjGenerator.CheckInterlockDrawingObjectPosition(_DestDrawObjectList) == false) {
MessageUtil.CreateAndShowMessageDialog("DrawObject Interlock check.", "Invalid DrawObject is found.");
}
_ObjGenerator.SaveDrawingObjectsToCSV(_DestDrawObjectList, "Manual");
double dpathlength = 0;
foreach (var item in _DestDrawObjectList) {
if (item is Line) {
if (((Line)item).MadebyRCC) {
dpathlength += ((Line)item).Distance;
}
} else if (item is Arc) {
if (((Arc)item).MadebyRCC) {
dpathlength += ((Arc)item).Length;
}
}
}
_ObjGenerator.GetAutoPath(out _PathList);
DrawObject();
}
private void SaveCoordinatesToCsv(double[] xCoordinates, double[] yCoordinates)
{
string savepath = Path.Combine(ConfigurationManager.AppSettings.Get("DATA_PATH"), "_vision", "EdgeContour",
string.Format($"{_VisionType}_{DateTime.Now.Year}_{DateTime.Now.Month}_{DateTime.Now.Day}_{DateTime.Now.ToString("HHmmss")}.csv"));
try {
using (StreamWriter writer = new StreamWriter(savepath)) {
writer.WriteLine("X,Y");
for (int i = 0; i < xCoordinates.Length; i++) {
writer.WriteLine($"{xCoordinates[i]},{yCoordinates[i]}");
}
}
} catch (Exception e) {
Log.E(e.Message);
}
}
private void SaveOffsetToCsv(double[] offset, double[] theta)
{
string savepath = Path.Combine(ConfigurationManager.AppSettings.Get("DATA_PATH"), "_vision", "EdgeContour", "Manual",
string.Format($"Offset_{DateTime.Now.Year}_{DateTime.Now.Month}_{DateTime.Now.Day}_{DateTime.Now.Hour}_{DateTime.Now.Minute}.csv"));
try {
using (StreamWriter writer = new StreamWriter(savepath)) {
writer.WriteLine("Theta,Offset");
for (int i = 0; i < offset.Length; i++) {
writer.WriteLine($"{theta[i]},{offset[i]}");
}
}
MessageUtil.CreateAndShowMessageDialog("Completed", $"Offset table is saved as {savepath}");
} catch (Exception e) {
Log.E(e.Message);
}
}
private void PerformCmdOffsetUpdate(object obj)
{
OpenFileDialog ofd = new OpenFileDialog();
DialogResult dr = ofd.ShowDialog();
string csvpath = "";
if (dr == DialogResult.OK) {
csvpath = ofd.FileName;
}
if (csvpath == "") {
return;
}
_ObjGenerator.setOffsetTable(csvpath, _SystemParam.LensMagnification, _SystemParam.CameraPixelSize);
}
private void SaveContoursToCsv(Point[][] maxcotours)
{
string folderPath = Path.Combine(ConfigurationManager.AppSettings.Get("DATA_PATH"), "_vision", "EdgeContour", "Manual");
string filepath = Path.Combine(folderPath,
string.Format($"EdgeContour_{DateTime.Now.Year}_{DateTime.Now.Month}_{DateTime.Now.Day}_{DateTime.Now:HHmmss}.csv"));
try {
if (!Directory.Exists(folderPath)) {
Directory.CreateDirectory(folderPath);
}
using (StreamWriter writer = new StreamWriter(filepath)) {
int index = 0;
writer.WriteLine("Index,X_pixel,Y_pixel,X_mm,Y_mm");
foreach (var contour in maxcotours) {
foreach (var point in contour) {
index++;
double convertX = (point.X - _ImageWidth / 2) * (_SystemParam.CameraPixelSize / _SystemParam.LensMagnification) / 1000;
double convertY = (-point.Y + _ImageHeight / 2) * (_SystemParam.CameraPixelSize / _SystemParam.LensMagnification) / 1000;
writer.WriteLine($"{index},{point.X},{point.Y},{convertX},{convertY}");
}
}
}
} catch (Exception e) {
Log.E(e.Message);
}
}
private void SaveCenterToCsv(double dCenterX, double dCenterY)
{
string savepath = Path.Combine(ConfigurationManager.AppSettings.Get("DATA_PATH"), "_vision", "EdgeContour", "Manual",
string.Format($"CenterDetect_{DateTime.Now.Year}_{DateTime.Now.Month}_{DateTime.Now.Day}.csv"));
try {
if (!File.Exists(savepath)) {
using (StreamWriter writer = new StreamWriter(savepath, false)) {
writer.WriteLine("DateTime, CenterX, CenterY");
writer.WriteLine($"{DateTime.Now.ToString("HH:mm:ss")}, {dCenterX}, {dCenterY}");
}
} else {
using (StreamWriter writer = new StreamWriter(savepath, true)) {
writer.WriteLine($"{DateTime.Now.ToString("HH:mm:ss")}, {dCenterX}, {dCenterY}");
}
}
} catch (Exception e) {
Log.E(e.Message);
}
}
private void PerformCmdCheckRadiusImage(object obj)
{
if (_MaskedImageMat == null) {
MessageUtil.CreateAndShowMessageDialog("Detect Edge is failed.", "Detect Edge is failed. Please Load image.");
return;
}
_Stopwatch.Start();
int Radius_Pixel = (int)(((Radius * _SystemParam.LensMagnification) / _SystemParam.CameraPixelSize) * 1000.0);
//objGenerator.FindEdge(ConvImg, Radius_Pixel, Margin, PointNum, CVThreshold, CVShrinkPixel, DetectPointPercent, out maxContour);
_ObjGenerator.FindCenterPoint(_ConvImageMat, CVThreshold, out _CenterPoint);
_Stopwatch.Stop();
Log.I($"OpenCV Time : {(float)_Stopwatch.ElapsedMilliseconds}");
_Stopwatch.Reset();
//UpdateDateCorrection(maxContour);
//DrawCVEdgeContour(maxContour);
DrawCenterPointRadius(_CenterPoint, Radius_Pixel);
}
private void PerformCmdDetectImage(object obj)
{
if (_MaskedImageMat == null) {
MessageUtil.CreateAndShowMessageDialog("Detect Edge is failed.", "Detect Edge is failed. Please Load image.");
return;
}
int centerX = 0, centerY = 0;
var mainPage = CommonHelper.GetMainPage();
_ScannerCanvasUserCtrl = mainPage.ScannerCanvasCtrlTeaching;
foreach (var item in _ScannerCanvasUserCtrl.Model.Layers[0].Objects) {
if (item is Arc) {
Arc arc = (Arc)item;
centerX = (int)(arc.Center.X * 1000.0 / _SystemParam.CameraPixelSize * _SystemParam.LensMagnification + _ImageWidth / 2);
centerY = (int)(-arc.Center.Y * 1000.0 / _SystemParam.CameraPixelSize * _SystemParam.LensMagnification + _ImageHeight / 2);
break;
}
}
_Stopwatch.Start();
//Autorun과 동일하게 할려면 Mil to mat 부터 진행해야하나 여기서는 EdgeDetect 시간만 확인
//maxContour = objGenerator.FindMaxContour(MaskedImg, CVThreshold, CVMorpIterations, CVMorpMaskSize);
//maxContour = objGenerator.FindMaxContour(MaskedImg, CVThreshold, CVShrinkPixel);
int Radius_Pixel = (int)(((Radius * _SystemParam.LensMagnification) / _SystemParam.CameraPixelSize) * 1000.0);
_ObjGenerator.FindEdge(_ConvImageMat, Radius_Pixel, Margin, PointNum, CVThreshold, centerX, centerY, CVShrinkPixel, CVShrinkPixel2, CVShrinkPixel3, CVShrinkPixel4, DetectPointPercent, out _MaxContour);
//maxContour = objGenerator.ReSizeFindMaxContour(ConvImg, 2, CVThreshold, CVShrinkPixel);
_Stopwatch.Stop();
Log.I($"OpenCV Time : {(float)_Stopwatch.ElapsedMilliseconds}");
_Stopwatch.Reset();
UpdateDateCorrection(_MaxContour);
DrawCVEdgeContour(_MaxContour);
}
private void UpdateDateCorrection(Point[][] maxContours)
{
if (maxContours.Count() < 1) {
return;
}
if (ContourCorrection.Count() != 0) {
ContourCorrection.Clear();
}
// MaxContour가 0일 경우 예외처리
if (_MaxContour[0].Count() < 1) {
Log.E("MaxContour is Null");
return;
}
int index = 0;
foreach (var contour in maxContours) {
foreach (var point in contour) {
ContourList cLItem = new ContourList();
cLItem.Index = index++;
cLItem.VisionX = point.X;
cLItem.VisionY = point.Y;
ContourCorrection.Add(cLItem);
}
}
}
private void DrawCenterPointRadius(Point center_point, double radius)
{
// Draw the contour on the image
_DetectImageMat = _ConvImageMat.Clone();
if (_VisionType == "OpenCV") {
Cv2.Circle(_DetectImageMat, center_point, 8, new Scalar(0, 255, 0), -1);
Cv2.Circle(_DetectImageMat, center_point, (int)radius, new Scalar(0, 255, 0), 2);
} else { //Cv2.DrawContours(detectImg, maxContour, -1, new Scalar(0, 255, 0), 2);
Cv2.Circle(_DetectImageMat, center_point, 3, new Scalar(0, 255, 0), -1);
Cv2.Circle(_DetectImageMat, center_point, (int)radius, new Scalar(0, 255, 0), 2);
}
ResultImage = _DetectImageMat.ToBitmapSource();
}
private void DrawCVEdgeContour(Point[][] maxContour)
{
// Draw the contour on the image
_DetectImageMat = _ConvImageMat.Clone();
// MaxContour가 0일 경우 예외처리
if (maxContour[0].Count() < 1) {
ResultImage = _DetectImageMat.ToBitmapSource();
//Log.E("MaxContour is Null");
return;
}
if (_VisionType == "OpenCV") {
Cv2.DrawContours(_DetectImageMat, maxContour, -1, new Scalar(0, 255, 0), 2);
} else {
Cv2.DrawContours(_DetectImageMat, maxContour, -1, new Scalar(0, 0, 255), 2);
}
ResultImage = _DetectImageMat.ToBitmapSource();
}
private void DrawCVCenterContour(Point[][] minContour)
{
// Draw the contour on the image
_DetectImageMat = _ConvImageMat.Clone();
Rect minRect = Cv2.BoundingRect(minContour[0]);
double centerX = minRect.X + (minRect.Width / 2);
double centerY = minRect.Y + (minRect.Height / 2);
double mCenterX = (((centerX - _DetectImageMat.Width / 2) * _SystemParam.CameraPixelSize) / _SystemParam.LensMagnification) / 1000.0;
double mCenterY = (((_DetectImageMat.Height / 2 - centerY) * _SystemParam.CameraPixelSize) / _SystemParam.LensMagnification) / 1000.0;
_CenterX = mCenterX;
_CenterY = mCenterY;
Cv2.DrawContours(_DetectImageMat, minContour, -1, new Scalar(0, 255, 0), 2);
Cv2.Line(_DetectImageMat, new Point(centerX - 50, centerY), new Point(centerX + 50, centerY), new Scalar(0, 0, 255), 5);
Cv2.Line(_DetectImageMat, new Point(centerX, centerY - 50), new Point(centerX, centerY + 50), new Scalar(0, 0, 255), 5);
ResultImage = _DetectImageMat.ToBitmapSource();
MessageUtil.CreateAndShowMessageDialog("Circle Find Success", string.Format("{0:0.00} , {1:0.00}", mCenterX, mCenterY));
}
private void PerformCmdLoadImage(object obj)
{
OpenFileDialog ofd = new OpenFileDialog();
DialogResult dr = ofd.ShowDialog();
if (dr == DialogResult.OK) {
_ImagePath = ofd.FileName;
}
if (_ImagePath == null) {
return;
}
#region OpenCV
_LoadImageMat = Cv2.ImRead(_ImagePath);
OriginImage = _LoadImageMat.ToBitmapSource();
_ConvImageMat = _LoadImageMat.Clone();
_ObjGenerator.SetImageSize(_LoadImageMat.Width, _LoadImageMat.Height);
_ImageWidth = _LoadImageMat.Width;
_ImageHeight = _LoadImageMat.Height;
_MaskedImageMat = _ObjGenerator.MaskingImage(_ConvImageMat, CVInnerCircleSize, CVOuterCircleSize);
MaskedImage = _MaskedImageMat.ToBitmapSource();
#endregion
//#region MIL
////buffer 설정, buffer 사이즈는 가져온 이미지의 사이즈로 넣어줘야함..
//MIL.MbufAllocColor(MilEnvironment.Instance.GetSystem(_cameraAgent._CamConfig.CamConnConfig.BoardSlotPos), 3, loadImg.Width, loadImg.Height, 8 + MIL.M_UNSIGNED, MIL.M_IMAGE + MIL.M_DISP + MIL.M_PROC, ref MILImage);
////이미지 로드
//MIL.MbufLoad(imagepath, MILImage);
////WPF Bitmapsource로 변환
//int width = (int)MIL.MbufInquire(MILImage, MIL.M_SIZE_X, MIL.M_NULL);
//int height = (int)MIL.MbufInquire(MILImage, MIL.M_SIZE_Y, MIL.M_NULL);
////int stride = width; // Assuming 8-bit grayscale image
//int stride = width * 3; // Assuming 24-bit BRG image
//byte[] imageData = new byte[width * height * 3];
////MIL.MbufGet(MILImage, imageData); // 8-bit일 경우 사용
//MIL.MbufGetColor(MILImage, MIL.M_PACKED + MIL.M_BGR24, MIL.M_ALL_BANDS, imageData);
////8-bit 1ch gray일 경우 사용
////BitmapSource bitmapSource = BitmapSource.Create(
//// width, height, 96, 96, System.Windows.Media.PixelFormats.Gray8, null, imageData, stride);
////32-bit 3ch bgr
//BitmapSource bitmapSource = BitmapSource.Create(
// width, height, 96, 96, System.Windows.Media.PixelFormats.Bgr24, null, imageData, stride);
////Convert bitmapsource to Mat
//ConvImg = bitmapSource.ToMat();
//// MIL 해제
//MIL.MbufFree(MILImage);
//#endregion
//int width = loadImg.Width;
//int height = loadImg.Height;
//int stride = width * 3;
//byte[] imageData = new byte[width * height * 3];
//imageData = loadImg.ToBytes();
//BitmapSource bitmapSource = BitmapSource.Create(
// loadImg.Width, loadImg.Height, 96, 96, System.Windows.Media.PixelFormats.Bgr24, null, loadImg.Data, loadImg.Step());
//ConvImg = bitmapSource.ToMat();
// WPF Image 컨트롤에 설정
//OriginImage = bitmapSource;
}
private void FindMilEdgeContour(double milThreshold, double milFillGapDist)
{
var camConfig = VisionEnv.AuroraEnv.DeviceManager.GetDeviceConfig(eCamId.CAM1.ToString()) as CamConfig;
MIL_ID MilSystem = MilEnvironment.Instance.GetSystem(camConfig.CamConnConfig.BoardType, camConfig.CamConnConfig.BoardSlotPos);
// Control Block for Disp
//MIL.MbufImport(imagepath, MIL.M_DEFAULT, MIL.M_RESTORE + MIL.M_NO_GRAB + MIL.M_NO_COMPRESS, MilSystem, ref MILImage);
MIL.MbufRestore(_ImagePath, MilSystem, ref MILImage);
MIL.MgraAlloc(MilSystem, ref MedgeCalculate_graphicContext);
MIL.MgraAllocList(MilSystem, MIL.M_DEFAULT, ref MedgeCalculate_graphicList);
MIL.MedgeAlloc(MilSystem, MIL.M_CONTOUR, MIL.M_DEFAULT, ref Edge_Contour_Context);
//MIL 컬러이미지를 Gray 이미지로 컨버팅
MIL.MbufAlloc2d(MilSystem, MIL.MbufInquire(MILImage, MIL.M_SIZE_X, MIL.M_NULL), MIL.MbufInquire(MILImage, MIL.M_SIZE_Y, MIL.M_NULL), 8 + MIL.M_UNSIGNED, MIL.M_IMAGE + MIL.M_PROC + MIL.M_DISP, ref MILGrayImage);
MIL.MimConvert(MILImage, MILGrayImage, MIL.M_RGB_TO_L);
MIL.MbufAlloc2d(MilSystem, MIL.MbufInquire(MILGrayImage, MIL.M_SIZE_X, MIL.M_NULL), MIL.MbufInquire(MILGrayImage, MIL.M_SIZE_Y, MIL.M_NULL), 1 + MIL.M_UNSIGNED, MIL.M_IMAGE + MIL.M_PROC + MIL.M_DISP, ref MilBinaryImage);
MIL.MimBinarize(MILGrayImage, MilBinaryImage, MIL.M_FIXED + MIL.M_GREATER_OR_EQUAL, milThreshold, MIL.M_NULL);
//MIL.MimBinarize(MILGrayImage, MilBinaryImage, MIL.M_BIMODAL + MIL.M_GREATER_OR_EQUAL, MIL.M_NULL, MIL.M_NULL);
// Control Block for Edge Contour Context
//MIL.MedgeControl(Edge_Contour_Context, MIL.M_MOMENT_ELONGATION, MIL.M_ENABLE);
MIL.MedgeControl(Edge_Contour_Context, MIL.M_FILL_GAP_DISTANCE, milFillGapDist);
MIL.MedgeControl(Edge_Contour_Context, MIL.M_CHAIN_ALL_NEIGHBORS, MIL.M_ENABLE);
MIL.MedgeControl(Edge_Contour_Context, MIL.M_FERET_MAX_DIAMETER + MIL.M_SORT1_DOWN, MIL.M_ENABLE);
// Set edge detection parameters
MIL.MedgeAllocResult(MilSystem, MIL.M_DEFAULT, ref Edge_Result);
// Calculate the edges.
MIL.MedgeCalculate(Edge_Contour_Context, MilBinaryImage, MIL.M_NULL, MIL.M_NULL, MIL.M_NULL, Edge_Result, MIL.M_DEFAULT);
// Exclude inner chains based on area
MIL_INT numberOfEdges = 0;
MIL.MedgeGetResult(Edge_Result, MIL.M_DEFAULT, MIL.M_NUMBER_OF_CHAINS + MIL.M_TYPE_MIL_INT, ref numberOfEdges);
if (numberOfEdges > 0) {
double[] diameters = new double[numberOfEdges];
MIL.MedgeGetResult(Edge_Result, MIL.M_DEFAULT, MIL.M_FERET_MAX_DIAMETER, diameters);
double maxdiameter = diameters.Max();
//가장 값인 큰 파라미터인 엣지 선택
MIL.MedgeSelect(Edge_Result, MIL.M_INCLUDE_ONLY, MIL.M_FERET_MAX_DIAMETER, MIL.M_EQUAL, maxdiameter, MIL.M_NULL);
// Retrieve the coordinates of the selected edge
MIL_INT numberOfPoints = 0;
MIL.MedgeGetResult(Edge_Result, MIL.M_DEFAULT, MIL.M_NUMBER_OF_CHAINED_EDGELS + MIL.M_TYPE_MIL_INT, ref numberOfPoints);
if (numberOfPoints > 0) {
_XCoordinates = new double[numberOfPoints];
_YCoordinates = new double[numberOfPoints];
MIL.MedgeGetResult(Edge_Result, MIL.M_DEFAULT, MIL.M_CHAIN_X, _XCoordinates);
MIL.MedgeGetResult(Edge_Result, MIL.M_DEFAULT, MIL.M_CHAIN_Y, _YCoordinates);
// Now xCoordinates and yCoordinates arrays contain the x and y coordinates of the edge points
// Calculate the center of the circle
double centerX = _XCoordinates.Average();
double centerY = _YCoordinates.Average();
for (int i = 0; i < numberOfPoints; i++) {
double dx = _XCoordinates[i] - centerX;
double dy = _YCoordinates[i] - centerY;
double distance = Math.Sqrt(dx * dx + dy * dy);
// Move the point inward by shrinkDistance
double newDistance = distance - MILShrinkDist;
double scale = newDistance / distance;
_XCoordinates[i] = centerX + dx * scale;
_YCoordinates[i] = centerY + dy * scale;
}
_EdgePoints = new Point[1][];
_EdgePoints[0] = new Point[numberOfPoints];
for (int i = 0; i < numberOfPoints; i++) {
_EdgePoints[0][i] = new Point((int)_XCoordinates[i], (int)_YCoordinates[i]);
}
}
//MIL_INT remainingEdges = 0;
//MIL.MedgeGetResult(Edge_Result, MIL.M_DEFAULT, MIL.M_NUMBER_OF_CHAINS + MIL.M_TYPE_MIL_INT, ref remainingEdges);
//Log.I($"{remainingEdges}");
}
}
private void DrawObject()
{
if (_PathList == null) {
return;
}
_DetectImageMat = _ConvImageMat.Clone();
foreach (var item in _PathList) {
if (item != null) {
if (item.GetType() == PathItem._PathType.Line) {
Point P1; Int64 P1X, P1Y;
Point P2; Int64 P2X, P2Y;
item.GetStart(out P1X, out P1Y); P1.X = Convert.ToInt32(P1X); P1.Y = Convert.ToInt32(P1Y);
item.GetEnd(out P2X, out P2Y); P2.X = Convert.ToInt32(P2X); P2.Y = Convert.ToInt32(P2Y);
Cv2.Line(_DetectImageMat, P1, P2, new Scalar(0, 0, 255), 6);
} else if (item.GetType() == PathItem._PathType.Arc) {
Point P1; Int64 P1X, P1Y;
Point P2; Int64 P2X, P2Y;
item.GetStart(out P1X, out P1Y); P1.X = Convert.ToInt32(P1X); P1.Y = Convert.ToInt32(P1Y);
item.GetEnd(out P2X, out P2Y); P2.X = Convert.ToInt32(P2X); P2.Y = Convert.ToInt32(P2Y);
Point PCenter; Int64 PX, PY;
item.GetCenter(out PX, out PY); PCenter.X = Convert.ToInt32(PX); PCenter.Y = Convert.ToInt32(PY);
double radius = Convert.ToDouble(item.GetRadius());
double dStartAngle = Math.Atan2((P1.Y - PCenter.Y), (P1.X - PCenter.X)) * (180 / Math.PI);
double dEndAngle = Math.Atan2((P2.Y - PCenter.Y), (P2.X - PCenter.X)) * (180 / Math.PI);
if (dStartAngle < 0) {
dStartAngle += 360;
}
if (dEndAngle < 0) {
dEndAngle += 360;
}
//if (PCenter.X < 0 || PCenter.Y < 0 || radius < 1000 || radius > 3000)
//{
// Cv2.Line(detectImg, P1, P2, new Scalar(0, 0, 255), 5);
// continue;
//}
//if (dStartAngle < 90 && dEndAngle > 270) {
// dEndAngle -= 360;
//}
//if (dStartAngle > 270 && dEndAngle < 90) {
// dStartAngle -= 360;
//}
if (_Draw_direction == Arc.eDirection.CW) {
if (dEndAngle < dStartAngle)
dEndAngle += 360;
} else {
if (dStartAngle < dEndAngle)
dStartAngle += 360;
}
Cv2.Ellipse(_DetectImageMat, PCenter, new Size(radius, radius), 0, dStartAngle, dEndAngle, new Scalar(0, 0, 255), 6);
}
}
}
ResultImage = _DetectImageMat.ToBitmapSource();
}
private void PerformCmdCenterDetectTest(object obj)
{
_MinContour = FindMinContourForCenter(_ConvImageMat, CVThreshold);
DrawCVCenterContour(_MinContour);
}
private void PerformCmdRecommendDetectParam(object obj)
{
var result = MessageDialog.Show(Application.Current.MainWindow, "RCC", $"Recommend EdgeDetect parameters(Threshold, ShrinkPixel)?",
MessageDialog.Type.AffirmativeAndNegative);
if (result == MessageDialog.Result.Negative) {
return;
}
// 최소값, 최대값 정해두고 그 안에서 찾자. 이거까지 parameter 로 뺄 필요는 없을듯
// mask image 로 할경우 ConvImg 를 MaskedImg 로 바꿔줄 것
// Pixel의 Center와 Pixel간 거리의 min, max를 구해서 minmax의 차이가 가장 작은 threshold를 추천한다
//double Threshold = 3;
// Check Radius를 사용하여 센터의 위치가 맞는 최소값을 기준으로 시작
double Threshold = CVThreshold;
int loopcnt = 20; // Threshold 시작부터 cnt 까지 증가하면서 찾는다.
Func<double, double, double> GetDistance = (x, y) => Math.Sqrt(x * x + y * y);
//double range = 9999;
//double RecommandedThreshold = 10;
double RecommandedThreshold = CVThreshold;
double min_dist = 9999;
double contour_min_dist = 9999;
//List<double> temp_dist = new List<double>();
int centerX = 0, centerY = 0;
foreach (var item in _ScannerCanvasUserCtrl.Model.Layers[0].Objects) {
if (item is Arc) {
Arc arc = (Arc)item;
centerX = (int)(arc.Center.X * 1000.0 / _SystemParam.CameraPixelSize * _SystemParam.LensMagnification + _ImageWidth / 2);
centerY = (int)(-arc.Center.Y * 1000.0 / _SystemParam.CameraPixelSize * _SystemParam.LensMagnification + _ImageHeight / 2);
break;
}
}
int Radius_Pixel = (int)(((Radius * _SystemParam.LensMagnification) / _SystemParam.CameraPixelSize) * 1000.0);
for (int i = 0; i < loopcnt; i++) {
//maxContour = objGenerator.ReSizeFindMaxContour(ConvImg, 2, Threshold, CVShrinkPixel);
//objGenerator.FindEdge(ConvImg, 1508, 10, 3600, Threshold, CVShrinkPixel, out maxContour);
_ObjGenerator.FindEdge(_ConvImageMat, Radius_Pixel, Margin, PointNum, Threshold, centerX, centerY, CVShrinkPixel, CVShrinkPixel2, CVShrinkPixel3, CVShrinkPixel4, DetectPointPercent, out _MaxContour);
//Point2f centroid = objGenerator.CalculateCentroid(maxContour[0]);
//if (Single.IsNaN(centroid.X) || Single.IsNaN(centroid.Y)) continue;
// min/max가 아닌 Check Radius를 통해 입력한 Radius 길이로 비교(min_dist)
//double min = 9999;
//double max = -9999;
for (int j = 0; j < _MaxContour[0].Length; j++) {
//double dist = GetDistance(maxContour[0][j].X - centroid.X, maxContour[0][j].Y - centroid.Y);
// Contour의 무게 중심 기준이 아닌, Check Radius를 토대로 찾은 센터를 기준으로 진행
double dist = GetDistance(_MaxContour[0][j].X - _CenterPoint.X, _MaxContour[0][j].Y - _CenterPoint.Y);
//if (dist < min)
// min = dist;
//if (dist > max)
// max = dist;
double diff_dist = Math.Abs(Radius_Pixel - dist);
if (diff_dist < contour_min_dist) {
contour_min_dist = diff_dist;
}
}
//if (range > max - min)
//{
// range = max - min;
// RecommandedThreshold = Threshold;
//}
//temp_dist.Add(contour_min_dist);
if (min_dist > contour_min_dist) {
min_dist = contour_min_dist;
RecommandedThreshold = Threshold;
}
Threshold = Threshold + 1;
}
CVThreshold = RecommandedThreshold;
_ObjGenerator.FindEdge(_ConvImageMat, Radius_Pixel, Margin, PointNum, CVThreshold, centerX, centerY, CVShrinkPixel, CVShrinkPixel2, CVShrinkPixel3, CVShrinkPixel4, DetectPointPercent, out _MaxContour);
UpdateDateCorrection(_MaxContour);
DrawCVEdgeContour(_MaxContour);
_ObjGenerator.SetInterlockProperties(DrawObjectDistanceRange, DrawObjectArcLengthMax, DrawObjectLengthSumDiffRange, DrawObjectCenterXYDiffRange);
if (!GetArcInfoFromRecipe()) {
return;
}
//객체 생성 후 객체의 시작점을 기준으로 센터까지의 거리를 구해서 평균 한 후 기존 arc의 반지름과의 차이가 가작 작은 값을 추천한다
int loopShrinkcnt = 60;
//double dMinLengthDiff = 9999;
double dMinRadiusDiff = 9999;
int ShrinkPixel = 0;
//int Radius_Pixel = (int)(((Radius * _systemParam.LensMagnification) / _systemParam.CameraPixelSize) * 1000.0);
for (int i = 0; i < loopShrinkcnt; i++) {
//maxContour = objGenerator.ReSizeFindMaxContour(ConvImg, 2, CVThreshold, i);
_ObjGenerator.FindEdge(_ConvImageMat, Radius_Pixel, Margin, PointNum, CVThreshold, centerX, centerY, CVShrinkPixel, CVShrinkPixel2, CVShrinkPixel3, CVShrinkPixel4, DetectPointPercent, out _MaxContour);
if (_VisionType == "OpenCV") {
_ObjGenerator.SetPolygonFromList(_MaxContour);
} else {
_ObjGenerator.SetPolygonFromList(_EdgePoints);
}
_ObjGenerator.CalculateAutoPath(MergeDist, MaxArcRadius, LineTolerance, ArcTolerance);
_ObjGenerator.ConvertPathItemToDrawingObjects(LineDefualtWidth, out _DestDrawObjectList);
_ObjGenerator.CheckInterlockDrawingObjectPosition(_DestDrawObjectList);
// objGenerator.fDetectedContourRadius 는 가장 먼 point 로 Radius 를 구해줘서 ShrinkPixel이 크게 잡힌다.
// point 들의 평균이 가장 작은 것으로 고쳐주자.
//double radiusdiff = Math.Abs(objGenerator.m_OriginArc.Radius - objGenerator.fDetectedContourRadius);
double radiusdiff = 0;
List<double> lsPointRadius = new List<double>();
foreach (var item in _DestDrawObjectList) {
lsPointRadius.Add(GetDistance((item.PF1.X - _ObjGenerator.DetectedContourCenter.X), (item.PF1.Y - _ObjGenerator.DetectedContourCenter.Y)));
}
radiusdiff = Math.Abs(lsPointRadius.Average() - _ObjGenerator.m_OriginArc.Radius);
if (radiusdiff < dMinRadiusDiff) {
dMinRadiusDiff = radiusdiff;
ShrinkPixel = i;
}
//double lengthdiff = Math.Abs(objGenerator.m_OriginArc.Length - objGenerator.dPathLengthSum);
//if (lengthdiff < dMinLengthDiff)
//{
// dMinLengthDiff = lengthdiff;
// ShrinkPixel = i;
//}
}
CVShrinkPixel = ShrinkPixel;
//maxContour = objGenerator.ReSizeFindMaxContour(ConvImg, 2, CVThreshold, CVShrinkPixel);
_ObjGenerator.FindEdge(_ConvImageMat, Radius_Pixel, Margin, PointNum, CVThreshold, centerX, centerY, CVShrinkPixel, CVShrinkPixel2, CVShrinkPixel3, CVShrinkPixel4, DetectPointPercent, out _MaxContour);
UpdateDateCorrection(_MaxContour);
DrawCVEdgeContour(_MaxContour);
//GenerateDrawingObject(obj);
GenerateDrawingObject();
}
private void PerformCmdRecipeUpdate(object obj)
{
var result = MessageDialog.Show(Application.Current.MainWindow, "RCC", $"Update the RCC object in the Recipe?",
MessageDialog.Type.AffirmativeAndNegative);
if (result == MessageDialog.Result.Negative) {
return;
}
RecipeUpdate();
}
private void PerformCmdRecipeUpdateObject(object obj)
{
var result = MessageDialog.Show(Application.Current.MainWindow, "Update Recipe", $"Update the object in the Recipe?",
MessageDialog.Type.AffirmativeAndNegative);
if (result == MessageDialog.Result.Negative) {
return;
}
RecipeUpdateObject();
}
public void PerformCmdOffsetSave(object obj)
{
OpenFileDialog ofd = new OpenFileDialog();
ofd.Multiselect = true;
DialogResult dr = ofd.ShowDialog();
if (dr != DialogResult.OK || ofd.FileNames.Length == 0) {
return;
}
var mainPage = CommonHelper.GetMainPage();
_ScannerCanvasUserCtrl = mainPage.ScannerCanvasCtrlTeaching;
Point2f ObjectCenter = new Point2f(1, 1);
double r = 0;
int centerX = 0, centerY = 0;
foreach (var item in _ScannerCanvasUserCtrl.Model.Layers[0].Objects) {
if (item is Arc) {
Arc arc = (Arc)item;
ObjectCenter = new Point2f((float)(_ImageWidth / 2 + arc.Center.X * _SystemParam.LensMagnification / _SystemParam.CameraPixelSize * 1000.0), (float)(_ImageHeight / 2 - arc.Center.Y * _SystemParam.LensMagnification / _SystemParam.CameraPixelSize * 1000.0));
r = arc.Radius * _SystemParam.LensMagnification / _SystemParam.CameraPixelSize * 1000.0;
centerX = (int)(arc.Center.X * 1000.0 / _SystemParam.CameraPixelSize * _SystemParam.LensMagnification + _ImageWidth / 2);
centerY = (int)(-arc.Center.Y * 1000.0 / _SystemParam.CameraPixelSize * _SystemParam.LensMagnification + _ImageHeight / 2);
break;
}
}
int Radius_Pixel = (int)(((Radius * _SystemParam.LensMagnification) / _SystemParam.CameraPixelSize) * 1000.0);
int img_cnt = 0;
double[] offset_list = new double[3600];
double[] theta_list = new double[3600];
foreach (String file in ofd.FileNames) {
Point[][] EdgeList;
_LoadImageMat = Cv2.ImRead(file);
if (_SystemParam.OffsetType == eOffsetType.CSV)
_ObjGenerator.SetOffsetType("Manual");
_ObjGenerator.FindEdge(_LoadImageMat, Radius_Pixel, Margin, 3600, CVThreshold, centerX, centerY, 0, 0, 0, 0, DetectPointPercent, out EdgeList);
if (_SystemParam.OffsetType == eOffsetType.CSV)
_ObjGenerator.SetOffsetType("CSV");
if (EdgeList[0].Length != 3600) {
Log.E($"Failed to Find 3600 points in {file}");
MessageUtil.CreateAndShowMessageDialog("Error", $"Failed to Find 3600 points in {file}");
return;
}
Point2f ContourCenter = _ObjGenerator.CalculateCentroid(EdgeList[0]);
var d = Math.Sqrt((ContourCenter.X - ObjectCenter.X) * (ContourCenter.X - ObjectCenter.X) + (ContourCenter.Y - ObjectCenter.Y) * (ContourCenter.Y - ObjectCenter.Y));
double theta2 = 0;
if (ObjectCenter.X > ContourCenter.X && ObjectCenter.Y >= ContourCenter.Y) {
theta2 = Math.Atan((ObjectCenter.Y - ContourCenter.Y) / (ObjectCenter.X - ContourCenter.X));
} else if (ObjectCenter.X > ContourCenter.X && ObjectCenter.Y <= ContourCenter.Y) {
theta2 = Math.Atan((-ObjectCenter.Y + ContourCenter.Y) / (ObjectCenter.X - ContourCenter.X));
} else if (ObjectCenter.X <= ContourCenter.X && ObjectCenter.Y < ContourCenter.Y) {
theta2 = Math.Atan((ContourCenter.X - ObjectCenter.X) / (ContourCenter.Y - ObjectCenter.Y));
} else {
theta2 = Math.Atan((ContourCenter.X - ObjectCenter.X) / (ObjectCenter.Y - ContourCenter.Y));
}
for (int i = 0; i < 3600; i++) {
double theta = 0;
double theta1 = 0.1 * i * Math.PI / 180;
theta_list[i] = 0.1 * i;
if (EdgeList[0][i].X > ContourCenter.X && EdgeList[0][i].Y >= ContourCenter.Y) {
if (ObjectCenter.X > ContourCenter.X && ObjectCenter.Y >= ContourCenter.Y) {
theta = Math.Max(theta1 - theta2, theta2 - theta1);
} else if (ObjectCenter.X > ContourCenter.X && ObjectCenter.Y <= ContourCenter.Y) {
theta = theta1 + theta2;
} else if (ObjectCenter.X <= ContourCenter.X && ObjectCenter.Y < ContourCenter.Y) {
theta = Math.PI / 2 + theta1 + theta2;
if (theta > Math.PI) theta = 2 * Math.PI - theta;
} else {
theta = theta2 + Math.PI / 2 - theta1;
}
} else if (EdgeList[0][i].X > ContourCenter.X && EdgeList[0][i].Y <= ContourCenter.Y) {
if (ObjectCenter.X > ContourCenter.X && ObjectCenter.Y >= ContourCenter.Y) {
theta = theta1 + theta2;
} else if (ObjectCenter.X > ContourCenter.X && ObjectCenter.Y <= ContourCenter.Y) {
theta = Math.Max(theta1 - theta2, theta2 - theta1);
} else if (ObjectCenter.X <= ContourCenter.X && ObjectCenter.Y < ContourCenter.Y) {
theta = theta2 + Math.PI / 2 - theta1;
} else {
theta = Math.PI / 2 + theta1 + theta2;
if (theta > Math.PI) theta = 2 * Math.PI - theta;
}
} else if (EdgeList[0][i].X <= ContourCenter.X && EdgeList[0][i].Y < ContourCenter.Y) {
if (ObjectCenter.X > ContourCenter.X && ObjectCenter.Y >= ContourCenter.Y) {
theta = Math.PI / 2 + theta1 + theta2;
if (theta > Math.PI) theta = 2 * Math.PI - theta;
} else if (ObjectCenter.X > ContourCenter.X && ObjectCenter.Y <= ContourCenter.Y) {
theta = theta1 + Math.PI / 2 - theta2;
} else if (ObjectCenter.X <= ContourCenter.X && ObjectCenter.Y < ContourCenter.Y) {
theta = Math.Max(theta1 - theta2, theta2 - theta1);
} else {
theta = Math.PI - theta1 - theta2;
}
} else {
if (ObjectCenter.X > ContourCenter.X && ObjectCenter.Y >= ContourCenter.Y) {
theta = theta1 + Math.PI / 2 - theta2;
} else if (ObjectCenter.X > ContourCenter.X && ObjectCenter.Y <= ContourCenter.Y) {
theta = Math.PI / 2 + theta1 + theta2;
if (theta > Math.PI) theta = 2 * Math.PI - theta;
} else if (ObjectCenter.X <= ContourCenter.X && ObjectCenter.Y < ContourCenter.Y) {
theta = Math.PI - theta1 - theta2;
} else {
theta = Math.Max(theta1 - theta2, theta2 - theta1);
}
}
var edge_distance = Math.Sqrt((EdgeList[0][i].X - ContourCenter.X) * (EdgeList[0][i].X - ContourCenter.X) + (EdgeList[0][i].Y - ContourCenter.Y) * (EdgeList[0][i].Y - ContourCenter.Y));
var object_distance = d * Math.Cos(theta) + Math.Sqrt(d * d * Math.Sin(theta) * Math.Sin(theta) + r * r);
var my_offset = (edge_distance - object_distance) * _SystemParam.CameraPixelSize / _SystemParam.LensMagnification / 1000.0;
offset_list[i] = (offset_list[i] * img_cnt + my_offset) / (img_cnt + 1);
}
img_cnt += 1;
}
SaveOffsetToCsv(offset_list, theta_list);
return;
}
private Point[][] FindMinContourForCenter(Mat oriImg, double threshold)
{
// Convert to grayscale
Mat grayImg = new Mat();
Cv2.CvtColor(oriImg, grayImg, ColorConversionCodes.BGR2GRAY);
// Apply threshold
Mat thresImg = new Mat();
Cv2.Threshold(grayImg, thresImg, threshold, 200, ThresholdTypes.BinaryInv);
// Find contours
Point[][] contours;
HierarchyIndex[] hierarchy;
Cv2.FindContours(thresImg, out contours, out hierarchy, RetrievalModes.CComp, ContourApproximationModes.ApproxSimple);
//string InvertedImgfilePath = Path.Combine(ConfigurationManager.AppSettings.Get("DATA_PATH"), "_vision", "EdgeContour", "ImgTest",
// string.Format($"InvertedImg{DateTime.Now.Year}_{DateTime.Now.Month}_{DateTime.Now.Day}.jpg"));
//Cv2.ImWrite(InvertedImgfilePath, InvertedImg);
int minWidth = 150;
int minWSize = int.MaxValue;
int minCntNo = 0;
for (int i = 0; i < contours.Length; i++) {
Rect rect = Cv2.BoundingRect(contours[i]);
if (rect.Width < minWidth) {
continue;
}
if (minWSize > rect.Width) {
minWSize = rect.Width;
minCntNo = i;
}
}
// Create an empty image to draw the minimum contour
Mat minCntImg = Mat.Zeros(oriImg.Size(), MatType.CV_8UC1);
// Draw the minimum contour
Cv2.DrawContours(minCntImg, contours, minCntNo, Scalar.White, -1);
// Find the contour again in the drawn image
Point[][] minContour;
Cv2.FindContours(minCntImg, out minContour, out hierarchy, RetrievalModes.External, ContourApproximationModes.ApproxSimple);
return minContour;
}
private void RecipeUpdate()
{
// Recipe 에서 볼수 있도록 한 임시 함수.
// 저장누르면 recipe 가 바뀌므로 주의
// Recipe 의 Layer 0번을 받아온다
var mainPage = CommonHelper.GetMainPage();
_ScannerCanvasUserCtrl = mainPage.ScannerCanvasCtrlTeaching;
for (int i = 0; i < (_ScannerCanvasUserCtrl.Model.Layers.Length); i++) {
List<IDrawObject> sourcelist = _ScannerCanvasUserCtrl.Model.Layers[i].Objects;
_ObjGenerator.ReplaceRCCObject(sourcelist, _DestDrawObjectList);
}
_ScannerCanvasUserCtrl.Update();
mainPage.UpdateObjetsInTreeView();
}
private void RecipeUpdateObject()
{
// Recipe 에서 볼수 있도록 한 임시 함수.
// 저장누르면 recipe 가 바뀌므로 주의
// Recipe 의 Layer 0번을 받아온다
var mainPage = CommonHelper.GetMainPage();
_ScannerCanvasUserCtrl = mainPage.ScannerCanvasCtrlTeaching;
for (int i = 0; i < (_ScannerCanvasUserCtrl.Model.Layers.Length); i++) {
List<IDrawObject> sourcelist = _ScannerCanvasUserCtrl.Model.Layers[i].Objects;
_ObjGenerator.ReplaceObject(sourcelist, _Offset_x, _Offset_y, _Offset_t, _Obejct_Center);
}
_ScannerCanvasUserCtrl.Update();
mainPage.UpdateObjetsInTreeView();
}
private void PerformCmdFindObject(object obj)
{
_DetectImageMat = _ConvImageMat.Clone();
_Stopwatch.Start();
Point[][] out_contours;
var (offsetX, offsetY, _, offsetT, cX_pixel, cY_pixel, ScX_pixel, ScY_pixel, radius) = _ObjGenerator.FindOffset(_ConvImageMat, CVThreshold, _Ref_x, _Ref_y, _Ref_t, out out_contours, SelectedOption);
if (out_contours[0].Length == 0) {
Log.E("Failed to Find Objects");
MessageUtil.CreateAndShowMessageDialog("Error", "Failed to Find Objects");
return;
}
Cv2.DrawContours(_DetectImageMat, out_contours, 0, new Scalar(0, 255, 255), 3);
if (SelectedOption == "Inzi") {
Cv2.Circle(_DetectImageMat, new Point(cX_pixel, cY_pixel), (int)radius, new Scalar(0, 255, 255), 3);
Cv2.DrawContours(_DetectImageMat, out_contours, 1, new Scalar(0, 255, 255), 3);
RotatedRect rotatedRect = Cv2.MinAreaRect(out_contours[1]);
Point2f[] vertices = rotatedRect.Points();
for (int i = 0; i < 4; i++) {
Cv2.Line(_DetectImageMat, (Point)vertices[i], (Point)vertices[(i + 1) % 4], new Scalar(0, 255, 0), 2);
}
Cv2.Circle(_DetectImageMat, new Point(cX_pixel, cY_pixel), 20, new Scalar(0, 0, 255), -1);
Cv2.Circle(_DetectImageMat, new Point(ScX_pixel, ScY_pixel), 20, new Scalar(0, 0, 255), -1);
cX_pixel -= _ConvImageMat.Width / 2;
cY_pixel = (_ConvImageMat.Height / 2 - cY_pixel);
_Obejct_Center = new UnitPoint((cX_pixel * _SystemParam.CameraPixelSize / _SystemParam.LensMagnification) / 1000.0, (cY_pixel * _SystemParam.CameraPixelSize / _SystemParam.LensMagnification) / 1000.0);
(_Offset_x, _Offset_y, _Offset_t) = ((offsetX * _SystemParam.CameraPixelSize / _SystemParam.LensMagnification) / 1000.0, (offsetY * _SystemParam.CameraPixelSize / _SystemParam.LensMagnification) / 1000.0, offsetT);
} else {
int px = ScX_pixel;
int py = ScY_pixel;
Cv2.Line(_DetectImageMat, new Point(cX_pixel, cY_pixel), new Point(px, py), new Scalar(0, 255, 0), 2);
cX_pixel -= _ConvImageMat.Width / 2;
cY_pixel = (_ConvImageMat.Height / 2 - cY_pixel);
_Obejct_Center = new UnitPoint((cX_pixel * _SystemParam.CameraPixelSize / _SystemParam.LensMagnification) / 1000.0, (cY_pixel * _SystemParam.CameraPixelSize / _SystemParam.LensMagnification) / 1000.0);
(_Offset_x, _Offset_y, _Offset_t) = ((offsetX * _SystemParam.CameraPixelSize / _SystemParam.LensMagnification) / 1000.0, (offsetY * _SystemParam.CameraPixelSize / _SystemParam.LensMagnification) / 1000.0, offsetT);
_Offset_t = _Offset_t * Math.PI / 180;
}
_Stopwatch.Stop();
Log.I($"Elapsed Time : {(float)_Stopwatch.ElapsedMilliseconds}");
Log.I($"Center Offset: ({(float)_Offset_x}(mm), {(float)_Offset_y}(mm)), Theta Offset: {(float)(_Offset_t * 180 / Math.PI)},");
_Stopwatch.Reset();
ResultImage = _DetectImageMat.ToBitmapSource();
OffsetX = _Offset_x;
OffsetY = _Offset_y;
OffsetTh = _Offset_t * 180 / Math.PI; //deg
}
private void PerformCmdFindReference(object obj)
{
_DetectImageMat = _ConvImageMat.Clone();
_Stopwatch.Start();
Point[][] out_contours;
if (SelectedOption == "LFW") {
//ref_x = 2412; ref_y = 1832;
var mainPage = CommonHelper.GetMainPage();
_ScannerCanvasUserCtrl = mainPage.ScannerCanvasCtrlTeaching;
foreach (var item in _ScannerCanvasUserCtrl.Model.Layers[0].Objects) {
if (item is Arc) {
Arc arc = (Arc)item;
_Ref_x = (int)(arc.Center.X * 1000.0 / _SystemParam.CameraPixelSize * _SystemParam.LensMagnification + _ImageWidth / 2);
_Ref_y = (int)(-arc.Center.Y * 1000.0 / _SystemParam.CameraPixelSize * _SystemParam.LensMagnification + _ImageHeight / 2);
break;
}
}
}
var (_, _, theta, _, cX_pixel, cY_pixel, ScX_pixel, ScY_pixel, radius) = _ObjGenerator.FindOffset(_ConvImageMat, CVThreshold, _Ref_x, _Ref_y, 0, out out_contours, SelectedOption);
if (out_contours[0].Length == 0) {
Log.E("Failed to Find Objects");
MessageUtil.CreateAndShowMessageDialog("Error", "Failed to Find Objects");
return;
}
_Stopwatch.Stop();
Log.I($"Elapsed Time : {(float)_Stopwatch.ElapsedMilliseconds}");
Cv2.DrawContours(_DetectImageMat, out_contours, 0, new Scalar(0, 255, 255), 3);
if (SelectedOption == "Inzi") {
Cv2.Circle(_DetectImageMat, new Point(cX_pixel, cY_pixel), (int)radius, new Scalar(0, 255, 255), 3);
RotatedRect rotatedRect = Cv2.MinAreaRect(out_contours[1]);
Point2f[] vertices = rotatedRect.Points();
for (int i = 0; i < 4; i++) {
Cv2.Line(_DetectImageMat, (Point)vertices[i], (Point)vertices[(i + 1) % 4], new Scalar(0, 255, 0), 2);
}
Cv2.Circle(_DetectImageMat, new Point(cX_pixel, cY_pixel), 20, new Scalar(0, 0, 255), -1);
Cv2.Circle(_DetectImageMat, new Point(ScX_pixel, ScY_pixel), 20, new Scalar(0, 0, 255), -1);
} else {
int px = ScX_pixel;
int py = ScY_pixel;
Cv2.Line(_DetectImageMat, new Point(cX_pixel, cY_pixel), new Point(px, py), new Scalar(0, 255, 0), 2);
theta = theta * Math.PI / 180;
}
_Ref_x = cX_pixel;
_Ref_y = cY_pixel;
_Ref_t = theta;
cX_pixel -= _ConvImageMat.Width / 2;
cY_pixel = (_ConvImageMat.Height / 2 - cY_pixel);
var ref_x_mm = (cX_pixel * _SystemParam.CameraPixelSize / _SystemParam.LensMagnification) / 1000.0;
var ref_y_mm = (cY_pixel * _SystemParam.CameraPixelSize / _SystemParam.LensMagnification) / 1000.0;
var ref_th_deg = theta * 180 / Math.PI;
Log.I($"Center: ({Math.Round(ref_x_mm, 2)}(mm), {Math.Round(ref_y_mm, 2)}(mm)), Theta: {ref_th_deg},");
_Stopwatch.Reset();
ResultImage = _DetectImageMat.ToBitmapSource();
//mm로 표시해주기 위해서 Log로 남기는 변수를 띄워준다
ReferenceX = Math.Round(ref_x_mm, 2);
ReferenceY = Math.Round(ref_y_mm, 2);
ReferenceTh = ref_th_deg;
}
private bool GetArcInfoFromRecipe()
{
// 여러개 쓸수 있지만 일단 한개부터 해보자
// 우선 첫번째 layer 만 해보자
var mainPage = CommonHelper.GetMainPage();
_ScannerCanvasUserCtrl = mainPage.ScannerCanvasCtrlTeaching;
foreach (var item in _ScannerCanvasUserCtrl.Model.Layers[0].Objects) {
if (item is Arc) {
Arc arc = (Arc)item;
if (arc.RCCArc == true) {
_ObjGenerator.SetBaseArc(arc);
_Draw_direction = arc.Direction;
return true; // 우선 한개라서 여기서 return. 여러개 할때는 삭제할것. 여러개하려면 arc 를 list 로 보내야할듯.
}
}
}
// 여기까지 오면 Arc 등록이 안된것임.
MessageUtil.CreateAndShowMessageDialog("Check the recipe.", "RCC Arc Unit is not in Recipe.");
return false;
}
#region Flying Vision + Detect Image + Generate Object + Welding Sequence Functions
private void PerformCmdFlyingSeqStart(object obj)
{
var result = MessageDialog.Show(Application.Current.MainWindow, "Scanner Scout", $"Start RCC Sequence?",
MessageDialog.Type.AffirmativeAndNegative);
if (result == MessageDialog.Result.Negative) {
return;
}
_SequenceDialog = new SequenceDialog($"RCC Sequence is running...") {
Owner = Application.Current.MainWindow
};
if (SequenceRunState.Idle == _AutoRunSMWSeq_Scout.RunState && SequenceRunState.Idle == _AutoRunSMWSeq_wo_Scout.RunState && SequenceRunState.Idle == _ManualRunRCC.RunState) {
// parameter 를 넘길 방법은?
_SequenceDialog.Show();
_ManualRunRCC.Start(new ScoutSeqParams(VisionRecipeManager.GetFovInfos()[0], eDisplayType.Machine_B), OnCompleted);
Log.I("SMW_RCC Manual Run Start");
} else {
Log.I("Check AutoRunSeq or ManualRunSeq Run State");
}
}
private void OnCompleted(SequenceActionResult result)
{
Application.Current.Dispatcher.InvokeAsync(() => {
if (_SequenceDialog != null) {
_SequenceDialog.Close();
}
MessageDialog.Show(Application.Current.MainWindow, "Sequence", "Complete.");
});
}
private void PerformCmdFlyingSeqRun(object obj)
{
const string RCCRUNCMD = "RCCRunCmd";
var bRCCRunCmd = _ManualRunRCC.SearchContext(RCCRUNCMD);
bRCCRunCmd = true;
}
private void PerformCmdFlyingSeqStop(object obj)
{
_ManualRunRCC.Stop();
Application.Current.Dispatcher.InvokeAsync(() => {
if (_SequenceDialog != null) {
_SequenceDialog.Close();
}
MessageDialog.Show(Application.Current.MainWindow, "Sequence", "Stop.");
});
}
private void OnCompleted(int result)
{
// 호출 방법은?
MessageDialog.Show(Application.Current.MainWindow, "Sequence", "Complete.");
}
private void OnUpdateManualRunResult(EventMessage obj)
{
try {
var updateManualRunResult = obj.Param as UpdateManualRunResult;
if (updateManualRunResult != null) {
_ConvImageMat = updateManualRunResult.ResultImage;
_PathList = updateManualRunResult.PathItemList;
}
DrawObject();
} catch (Exception ex) {
}
}
#endregion
public class ContourList
{
public int Index { get; set; }
public float VisionX { get; set; }
public float VisionY { get; set; }
//public int ScannerX { get; set; }
//public int ScannerY { get; set; }
}
}
}
public class ButtonViewModel
{
public string Name { get; set; }
public ICommand Command { get; set; }
public ButtonViewModel(string name, ICommand command)
{
Name = name;
Command = command;
}
}