/* * Copyright (c) 2025 LG Electronics Inc. * SPDX-License-Identifier: LicenseRef-LGE-Proprietary */ using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace VisionCommon { public class BaseResult { public ImagePoint ImagePosition = new ImagePoint(); public StaticPoint MaterialPosition = new StaticPoint(); public Angle Angle = new Angle(); public BaseResult() { } public BaseResult(ImagePoint position, Angle angle) { ImagePosition = position.Clone() as ImagePoint; Angle = angle.Clone() as Angle; } public override string ToString() { return string.Format($"{ImagePosition}, {MaterialPosition}, {Angle}"); } public string ConvertMaterialPosition() { if (VisionSettingManager.VisionSetting.CoordUnit == eCoordUnit.UM) { return String.Format( "S({0:0.0}, {1:0.0})", MathUtil.ConvertUnitMilliToMicro(MaterialPosition.X), MathUtil.ConvertUnitMilliToMicro(MaterialPosition.Y)); } return String.Format( "S({0:0.00}, {1:0.00})", MaterialPosition.X, MaterialPosition.Y); } public BaseResult Clone() { return new BaseResult() { ImagePosition = this.ImagePosition.Clone() as ImagePoint, MaterialPosition = this.MaterialPosition.Clone() as StaticPoint, Angle = this.Angle.Clone() as Angle }; } } public class ModelFinderResult : BaseResult { public ImagePoint Offset { get; set; } public double Score { get; set; } public ModelFinderResult( ImagePoint position, ImagePoint offset, Angle angle, double score) : base(position, angle) { Offset = offset.Clone() as ImagePoint; Score = score; } } public class ShapeModelFinderResult : ModelFinderResult { public double Width { get; set; } public double Height { get; set; } public double Radius { get; set; } public ShapeModelFinderResult( ImagePoint position, ImagePoint offset, Angle angle, double score, double width, double height, double radius) : base(position, offset, angle, score) { Width = width; Height = height; Radius = radius; } } public class PatternMatchingResult : BaseResult { public ImagePoint Offset { get; set; } public double Score { get; set; } public PatternMatchingResult( ImagePoint position, ImagePoint offset, Angle angle, double score) : base(position, angle) { Offset = offset.Clone() as ImagePoint; Score = score; } } public class EdgeFinderResult : BaseResult { public double LineA { get; set; } public double LineB { get; set; } public double LineC { get; set; } public EdgeFinderResult( ImagePoint position, Angle angle, double lineA, double lineB, double lineC) : base(position, angle) { LineA = lineA; LineB = lineB; LineC = lineC; } } /// /// 직선의 방정식 : Ax + By + C = 0 /// public class LineEquation : ICloneable { /// /// 직선의 방정식 파라미터 A /// public double A { get; set; } /// /// 직선의 방정식 파라미터 B /// public double B { get; set; } /// /// 직선의 방정식 파라미터 C /// public double C { get; set; } /// /// 직선의 파라미터로 방정식 생성 /// /// 직선의 방정식 파라미터 A /// 직선의 방정식 파라미터 B /// 직선의 방정식 파라미터 C public LineEquation(double a, double b, double c) { A = a; B = b; C = c; } /// /// 직선을 지나는 두 점으로 방정식 생성 /// /// 직선을 지나가는 좌표1 X /// 직선을 지나가는 좌표1 Y /// 직선을 지나가는 좌표2 X /// 직선을 지나가는 좌표2 Y public LineEquation(double x1, double y1, double x2, double y2) { if (x1 == x2) { // x1, x2가 같을 경우 직선이 만들어질 수 없으므로, 0에 가까운 오프셋을 줘서 라인이 생성되도록 한다. x2 += 0.000001; // 0.001 um } if (y1 == y2) { // y1, y2가 같을 경우 직선이 만들어질 수 없으므로, 0에 가까운 오프셋을 줘서 라인이 생성되도록 한다. y2 += 0.000001; // 0.001 um } A = (y2 - y1) / (x2 - x1); B = -1; C = (-1) * A * x1 + y1; } /// /// 파라미터 Y좌표에 대응하는 X좌표 /// /// 임의의 Y좌표 /// public double GetX(double y) { return ((B * y) + C) * (-1) / A; } /// /// 파라미터 X좌표에 대응하는 Y좌표 /// /// 임의의 X좌표 /// public double GetY(double x) { return ((A * x) + C) * (-1) / B; } /// /// 복제 (ICloneable) /// /// object(LineEquation) public object Clone() { return new LineEquation(A, B, C); } } public class LineFinderResult : BaseResult { public LineEquation LineEquation { get; set; } public object ContextId { get; set; } public ROI FindRoi { get; set; } public eFoundStatus Status { get; set; } public double Contrast { get; set; } = 0.0; public double Strength { get; set; } = 0.0; public LineFinderResult() { LineEquation = new LineEquation(0,0,0); ContextId = null; } public LineFinderResult( ImagePoint position, Angle angle, LineEquation lineEquation, object contextId) : base(position, angle) { LineEquation = lineEquation; ContextId = contextId; } public LineFinderResult( ImagePoint position, Angle angle, LineEquation lineEquation, ROI roiDetail, double contrast, double strength, object contextId) : base(position, angle) { LineEquation = lineEquation; FindRoi = roiDetail; Contrast = contrast; Strength = strength; ContextId = contextId; } } public class CaliperResult : BaseResult { public ImagePoint ImagePositionSecond { get; set; } public StaticPoint MaterialPositionSecond { get; set; } = new StaticPoint(); public ImagePoint ImagePositionSecond_VI { get; set; } // Vertical Intersection public StaticPoint MaterialPositionSecond_VI { get; set; } = new StaticPoint(); // Vertical Intersection public LineEquation LineEquationFirst { get; set; } public LineEquation LineEquationSecond { get; set; } public PatternResult PatternResultFirst { get; set; } // Mid Point 1 public PatternResult PatternResultSecond { get; set; } // Mid Point 2 public double WidthPx { get; set; } public double WidthMm { get; private set; } public void SetWidthMm(ePatternType patternType) { if (patternType == ePatternType.Caliper) { this.WidthMm = MathUtil.CalculateDistance(MaterialPosition, MaterialPositionSecond); // Caliper } else { this.WidthMm = MathUtil.CalculateDistance(MaterialPosition, MaterialPositionSecond_VI); // Line Width Pattern Block } } public CaliperResult() { } public CaliperResult( ImagePoint position1, ImagePoint position2, ImagePoint position2_VI, LineEquation lineEquation1, LineEquation lineEquation2, PatternResult patternResult1, PatternResult patternResult2, double widthPx) : base(position1, new Angle()) { ImagePositionSecond = position2; ImagePositionSecond_VI = position2_VI; LineEquationFirst = lineEquation1; LineEquationSecond = lineEquation2; PatternResultFirst = patternResult1; PatternResultSecond = patternResult2; WidthPx = widthPx; } public CaliperResult Clone() { return new CaliperResult() { ImagePosition = base.ImagePosition.Clone() as ImagePoint, ImagePositionSecond = this.ImagePositionSecond.Clone() as ImagePoint, MaterialPosition = base.MaterialPosition.Clone() as StaticPoint, MaterialPositionSecond = this.MaterialPositionSecond.Clone() as StaticPoint, ImagePositionSecond_VI = this.ImagePositionSecond_VI.Clone() as ImagePoint, MaterialPositionSecond_VI = this.MaterialPositionSecond_VI.Clone() as StaticPoint, LineEquationFirst = this.LineEquationFirst.Clone() as LineEquation, LineEquationSecond = this.LineEquationSecond.Clone() as LineEquation, PatternResultFirst = this.PatternResultFirst, PatternResultSecond = this.PatternResultSecond, WidthPx = this.WidthPx, WidthMm = this.WidthMm }; } } public class CodeResult : BaseResult { public string CodeType { get; set; } public ImagePoint Offset { get; set; } public string Code { get; set; } public double Score { get; set; } public CodeResult(string codeType, ImagePoint position, ImagePoint offset, Angle angle, double score, string code) : base(position, angle) { CodeType = codeType; Offset = offset.Clone() as ImagePoint; Score = score; Code = code; } } public enum eOcrType { StrRead, // String Read 모듈 OcrRead, // OCR Read 모듈 Tesseract // Tesseract AI 모듈 } public class OcrResult : BaseResult { public eOcrType OcrType { get; set; } public ImagePoint Offset { get; set; } public double Score { get; set; } public string Text { get; set; } public ROI FindRoi { get; set; } public eFoundStatus Status { get; set; } = eFoundStatus.None; public OcrResult() { } public OcrResult( eOcrType ocrType, ImagePoint position, ImagePoint offset, Angle angle, double score, string text, ROI findRoi, eFoundStatus status) : base(position, angle) { OcrType = ocrType; Offset = offset.Clone() as ImagePoint; Score = score; Text = text; FindRoi = findRoi.Clone() as ROI; Status = status; } } public class BlobResult : BaseResult { public ImagePoint Offset { get; set; } public double Area { get; set; } public BlobResult(ImagePoint position, ImagePoint offset, double area) : base(position, new Angle()) { Area = area; } } public class BrightnessResult : BaseResult { public int Min { get; set; } public int Max { get; set; } public int Avg { get; set; } public BrightnessResult() { } public BrightnessResult(ImagePoint position, int min, int max, int avg) : base(position, new Angle()) { Min = min; Max = max; Avg = avg; } public BrightnessResult Clone() { return new BrightnessResult() { ImagePosition = base.ImagePosition.Clone() as ImagePoint, Min = this.Min, Max = this.Max, Avg = this.Avg }; } } public class LineIntersectionResult : BaseResult { public ImagePoint Offset { get; set; } public PatternResult Line1PatternResult { get; set; } public PatternResult Line2PatternResult { get; set; } public LineIntersectionResult( ImagePoint position, ImagePoint offset, PatternResult line1PatternResult, PatternResult line2PatternResult) : base(position, new Angle()) { Offset = offset.Clone() as ImagePoint; Line1PatternResult = line1PatternResult; Line2PatternResult = line2PatternResult; } } }