347 lines
12 KiB
C#
347 lines
12 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Text;
|
|
using System.Threading.Tasks;
|
|
|
|
namespace VisionCommon {
|
|
public class BaseResult {
|
|
public ImagePoint ImagePosition;
|
|
public StaticPoint MaterialPosition = new StaticPoint();
|
|
public Angle 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 double InnerRadius { get; set; }
|
|
public double OuterRadius { get; set; }
|
|
|
|
public ShapeModelFinderResult(
|
|
ImagePoint position, ImagePoint offset, Angle angle, double score, double width, double height, double radius, double innerRadius, double outerRadius)
|
|
: base(position, offset, angle, score) {
|
|
Width = width;
|
|
Height = height;
|
|
Radius = radius;
|
|
InnerRadius = innerRadius;
|
|
OuterRadius = outerRadius;
|
|
}
|
|
}
|
|
|
|
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;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// 직선의 방정식 : Ax + By + C = 0
|
|
/// </summary>
|
|
public class LineEquation : ICloneable {
|
|
/// <summary>
|
|
/// 직선의 방정식 파라미터 A
|
|
/// </summary>
|
|
public double A { get; set; }
|
|
/// <summary>
|
|
/// 직선의 방정식 파라미터 B
|
|
/// </summary>
|
|
public double B { get; set; }
|
|
/// <summary>
|
|
/// 직선의 방정식 파라미터 C
|
|
/// </summary>
|
|
public double C { get; set; }
|
|
|
|
/// <summary>
|
|
/// 직선의 파라미터로 방정식 생성
|
|
/// </summary>
|
|
/// <param name="a">직선의 방정식 파라미터 A</param>
|
|
/// <param name="b">직선의 방정식 파라미터 B</param>
|
|
/// <param name="c">직선의 방정식 파라미터 C</param>
|
|
public LineEquation(double a, double b, double c) {
|
|
A = a;
|
|
B = b;
|
|
C = c;
|
|
}
|
|
|
|
/// <summary>
|
|
/// 직선을 지나는 두 점으로 방정식 생성
|
|
/// </summary>
|
|
/// <param name="x1">직선을 지나가는 좌표1 X</param>
|
|
/// <param name="y1">직선을 지나가는 좌표1 Y</param>
|
|
/// <param name="x2">직선을 지나가는 좌표2 X</param>
|
|
/// <param name="y2">직선을 지나가는 좌표2 Y</param>
|
|
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;
|
|
}
|
|
|
|
/// <summary>
|
|
/// 파라미터 Y좌표에 대응하는 X좌표
|
|
/// </summary>
|
|
/// <param name="y">임의의 Y좌표</param>
|
|
/// <returns></returns>
|
|
public double GetX(double y) {
|
|
return ((B * y) + C) * (-1) / A;
|
|
}
|
|
|
|
/// <summary>
|
|
/// 파라미터 X좌표에 대응하는 Y좌표
|
|
/// </summary>
|
|
/// <param name="x">임의의 X좌표</param>
|
|
/// <returns></returns>
|
|
public double GetY(double x) {
|
|
return ((A * x) + C) * (-1) / B;
|
|
}
|
|
|
|
/// <summary>
|
|
/// 복제 (ICloneable)
|
|
/// </summary>
|
|
/// <returns>object(LineEquation)</returns>
|
|
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 void AddFoundStatus(eFoundStatus status) {
|
|
Status = status;
|
|
}
|
|
public void AddFoundStatus(ROI roiDetail) {
|
|
FindRoi = roiDetail;
|
|
}
|
|
}
|
|
|
|
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 ImagePoint Offset { get; set; }
|
|
public string Code { get; set; }
|
|
|
|
public CodeResult(ImagePoint position, ImagePoint offset, Angle angle, string code)
|
|
: base(position, angle) {
|
|
Offset = offset.Clone() as ImagePoint;
|
|
Code = code;
|
|
}
|
|
}
|
|
|
|
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;
|
|
}
|
|
}
|
|
}
|