305 lines
12 KiB
C#
305 lines
12 KiB
C#
/*
|
|
* Copyright (c) 2025 LG Electronics Inc.
|
|
* SPDX-License-Identifier: LicenseRef-LGE-Proprietary
|
|
*/
|
|
using Aurora.Api;
|
|
using CogCommon;
|
|
using VisionCommon;
|
|
using Hermes;
|
|
using Cognex.VisionPro;
|
|
using Cognex.VisionPro.Caliper;
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Diagnostics;
|
|
using System.Runtime.Serialization.Formatters.Binary;
|
|
|
|
namespace CogPattern {
|
|
/// <summary>
|
|
/// CaliperRunParam 클래스
|
|
/// </summary>
|
|
public class CaliperRunParam : IRunParam, ICloneable {
|
|
/// <summary>
|
|
/// PolarityFirst
|
|
/// </summary>
|
|
public ePolarity PolarityFirst { get; set; } = ePolarity.Any;
|
|
/// <summary>
|
|
/// PolaritySecond
|
|
/// </summary>
|
|
public ePolarity PolaritySecond { get; set; } = ePolarity.Any;
|
|
/// <summary>
|
|
/// ContrastThreshold
|
|
/// </summary>
|
|
public double ContrastThreshold { get; set; } = 5;
|
|
/// <summary>
|
|
/// FilterHalfSizeInPixels
|
|
/// </summary>
|
|
public int FilterHalfSizeInPixels { get; set; } = 2;
|
|
/// <summary>
|
|
/// EdgeWidth
|
|
/// </summary>
|
|
public double EdgeWidth { get; set; } = 10;
|
|
/// <summary>
|
|
/// FindROI
|
|
/// </summary>
|
|
public ROI FindROI { get; set; }
|
|
/// <summary>
|
|
/// Clone
|
|
/// </summary>
|
|
public object Clone() {
|
|
return new CaliperRunParam() {
|
|
PolarityFirst = PolarityFirst,
|
|
PolaritySecond = PolaritySecond,
|
|
ContrastThreshold = ContrastThreshold,
|
|
FilterHalfSizeInPixels = FilterHalfSizeInPixels,
|
|
EdgeWidth = EdgeWidth,
|
|
FindROI = FindROI.Clone() as ROI
|
|
};
|
|
}
|
|
}
|
|
|
|
internal class CogMeasureWidth {
|
|
private static Logger _Logger = new Logger(typeof(CogMeasureWidth).Name);
|
|
|
|
public static CogCaliperTool CreateTool() {
|
|
CogCaliperTool cogCaliperTool = new CogCaliperTool();
|
|
return cogCaliperTool;
|
|
}
|
|
|
|
public static CogCaliperTool LoadTool(string filePath) {
|
|
return (CogCaliperTool)CogSerializer.LoadObjectFromFile(
|
|
filePath,
|
|
typeof(BinaryFormatter),
|
|
CogSerializationOptionsConstants.Minimum);
|
|
}
|
|
|
|
public static int SaveTool(CogCaliperTool cogCaliperTool, string filePath) {
|
|
if (cogCaliperTool != null && filePath != null) {
|
|
CogSerializer.SaveObjectToFile(
|
|
cogCaliperTool,
|
|
filePath,
|
|
typeof(BinaryFormatter),
|
|
CogSerializationOptionsConstants.Minimum);
|
|
|
|
return E1.OK;
|
|
}
|
|
|
|
return E1.GENERIC;
|
|
}
|
|
|
|
public static void FreeTool(CogCaliperTool cogCaliperTool) {
|
|
if (cogCaliperTool != null) {
|
|
cogCaliperTool = null;
|
|
}
|
|
}
|
|
|
|
public static ROI GetFindROI(CogCaliperTool cogCaliperTool) {
|
|
var findRoi = CogEnvironment.ConvertToRoi(cogCaliperTool.Region);
|
|
|
|
return new ROI(
|
|
new ImagePoint(findRoi.CenterX, findRoi.CenterY),
|
|
findRoi.Width,
|
|
findRoi.Height,
|
|
findRoi.Angle);
|
|
}
|
|
|
|
public static int SetFindROI(CogCaliperTool cogCaliperTool, ROI findRoi) {
|
|
if (findRoi.Width > 0 && findRoi.Height > 0) {
|
|
if (cogCaliperTool != null) {
|
|
cogCaliperTool.Region = CogEnvironment.ConvertToCogRectangleAffine(findRoi);
|
|
}
|
|
}
|
|
|
|
return E1.OK;
|
|
}
|
|
|
|
public static PatternResult Find(
|
|
CogCaliperTool cogCaliperTool,
|
|
ICogImage image,
|
|
Func<CogCaliperTool, double, PatternResult> funcExtractResults,
|
|
ROI findRoi) {
|
|
var patternResult = new PatternResult();
|
|
var oldFindRoi = GetFindROI(cogCaliperTool);
|
|
|
|
try {
|
|
SetFindROI(cogCaliperTool, findRoi);
|
|
patternResult = Find(cogCaliperTool, image, funcExtractResults);
|
|
}
|
|
catch (Exception e) {
|
|
_Logger.FuncE(e.Message);
|
|
}
|
|
finally {
|
|
SetFindROI(cogCaliperTool, oldFindRoi);
|
|
}
|
|
|
|
return patternResult;
|
|
}
|
|
|
|
public static PatternResult Find(
|
|
CogCaliperTool cogCaliperTool,
|
|
ICogImage image,
|
|
Func<CogCaliperTool, double, PatternResult> funcExtractResults) {
|
|
|
|
var timeFind = new Stopwatch();
|
|
timeFind.Start();
|
|
|
|
cogCaliperTool.InputImage = (CogImage8Grey)image;
|
|
cogCaliperTool.Run();
|
|
|
|
timeFind.Stop();
|
|
double tactTime = timeFind.ElapsedMilliseconds;
|
|
|
|
return funcExtractResults(cogCaliperTool, tactTime);
|
|
}
|
|
|
|
public static void DrawSubPositions(CogCaliperTool cogCaliperTool, ICogCameraDisplay cogCameraDisplay) {
|
|
if (CogMeasureCommon.IsEdgeFound(cogCaliperTool)) {
|
|
var crosses = new List<Cross>();
|
|
int crossLength = 15;
|
|
|
|
foreach (CogCaliperEdge edge in cogCaliperTool.Results.Edges) {
|
|
if (edge.PositionX != 0 || edge.PositionY != 0) {
|
|
var point = new ImagePoint(edge.PositionX, edge.PositionY);
|
|
crosses.Add(new Cross(point, crossLength));
|
|
}
|
|
}
|
|
cogCameraDisplay.AddCrosses(crosses, GraphicColors.PatternFoundOK);
|
|
}
|
|
}
|
|
|
|
public static IRunParam GetRunParam(CogCaliperTool cogCaliperTool) {
|
|
return new CaliperRunParam() {
|
|
PolarityFirst = CogMeasureCommon.ConvertToPolarity(cogCaliperTool.RunParams.Edge0Polarity),
|
|
PolaritySecond = CogMeasureCommon.ConvertToPolarity(cogCaliperTool.RunParams.Edge1Polarity),
|
|
ContrastThreshold = cogCaliperTool.RunParams.ContrastThreshold,
|
|
FilterHalfSizeInPixels = cogCaliperTool.RunParams.FilterHalfSizeInPixels,
|
|
EdgeWidth = Math.Abs(cogCaliperTool.RunParams.Edge0Position) + Math.Abs(cogCaliperTool.RunParams.Edge1Position),
|
|
FindROI = GetFindROI(cogCaliperTool)
|
|
};
|
|
}
|
|
|
|
public static int SetRunParam(CogCaliperTool cogCaliperTool, IRunParam runParam) {
|
|
if (runParam is CaliperRunParam) {
|
|
var param = runParam as CaliperRunParam;
|
|
cogCaliperTool.RunParams.EdgeMode = CogCaliperEdgeModeConstants.Pair; // Edge0,1 하나씩 따기
|
|
cogCaliperTool.RunParams.ContrastThreshold = param.ContrastThreshold;
|
|
cogCaliperTool.RunParams.FilterHalfSizeInPixels = param.FilterHalfSizeInPixels;
|
|
cogCaliperTool.RunParams.MaxResults = 1; // Edge당 1개 라인 따기
|
|
cogCaliperTool.RunParams.Edge0Position = (Math.Abs(param.EdgeWidth) / 2) * -1;
|
|
cogCaliperTool.RunParams.Edge1Position = (Math.Abs(param.EdgeWidth) / 2);
|
|
cogCaliperTool.RunParams.Edge0Polarity = CogMeasureCommon.ConvertToCogCaliperPolarity(param.PolarityFirst);
|
|
cogCaliperTool.RunParams.Edge1Polarity = CogMeasureCommon.ConvertToCogCaliperPolarity(param.PolaritySecond);
|
|
SetFindROI(cogCaliperTool, param.FindROI);
|
|
|
|
return E1.OK;
|
|
}
|
|
|
|
return E1.GENERIC;
|
|
}
|
|
|
|
public static PatternResult Find(CogCaliperTool cogCaliperTool, ICogImage image, IRunParam runParam) {
|
|
SetRunParam(cogCaliperTool, runParam);
|
|
return Find(cogCaliperTool, image);
|
|
}
|
|
|
|
public static PatternResult Find(CogCaliperTool cogCaliperTool, ICogImage image, ROI findRoi) {
|
|
return Find(cogCaliperTool, image, ExtractResults, findRoi);
|
|
}
|
|
|
|
public static PatternResult Find(CogCaliperTool cogCaliperTool, ICogImage image) {
|
|
return Find(cogCaliperTool, image, ExtractResults);
|
|
}
|
|
|
|
private static PatternResult ExtractResults(CogCaliperTool cogCaliperTool, double tactTime) {
|
|
var results = new List<CaliperResult>();
|
|
|
|
if (CogMeasureCommon.IsEdgeFound(cogCaliperTool)) {
|
|
double positionFirstX = cogCaliperTool.Results.Edges[0].PositionX;
|
|
double positionFirstY = cogCaliperTool.Results.Edges[0].PositionY;
|
|
var positionFirst = new ImagePoint(positionFirstX, positionFirstY);
|
|
|
|
double positionSecondX = cogCaliperTool.Results.Edges[1].PositionX;
|
|
double positionSecondY = cogCaliperTool.Results.Edges[1].PositionY;
|
|
var positionSecond = new ImagePoint(positionSecondX, positionSecondY);
|
|
|
|
double widthPx = MathUtil.CalculateDistance(positionFirst, positionSecond);
|
|
|
|
results.Add(new CaliperResult(
|
|
positionFirst,
|
|
positionSecond,
|
|
new ImagePoint(),
|
|
new LineEquation(1, 1, 1), // 라인방정식 없음
|
|
new LineEquation(1, 1, 1),
|
|
new PatternResult(),
|
|
new PatternResult(),
|
|
widthPx));
|
|
}
|
|
|
|
return new PatternResult() {
|
|
Status = (results.Count > 0) ? eFoundStatus.FoundOK : eFoundStatus.NotFound,
|
|
Results = results,
|
|
FindRoi = GetFindROI(cogCaliperTool),
|
|
TactTimeInMilliSec = tactTime
|
|
};
|
|
}
|
|
|
|
public static void Draw(CogCaliperTool cogCaliperTool, PatternResult patternResult, ICogCameraDisplay cogCameraDisplay) {
|
|
DrawSubPositions(cogCaliperTool, cogCameraDisplay);
|
|
DrawText(patternResult, cogCameraDisplay);
|
|
//DrawWidth(patternResult, cogCameraDisplay);
|
|
DrawWidth(cogCaliperTool, cogCameraDisplay);
|
|
}
|
|
|
|
public static PatternResult GetNotFoundPatternResult() {
|
|
return new PatternResult() {
|
|
Status = eFoundStatus.NotFound,
|
|
Results = new List<CaliperResult>()
|
|
};
|
|
}
|
|
|
|
private static void DrawText(PatternResult patternResult, ICogCameraDisplay cogCameraDisplay) {
|
|
if (patternResult.Status == eFoundStatus.FoundOK) {
|
|
foreach (BaseResult baseResult in patternResult.Results) {
|
|
var caliperResult = baseResult as CaliperResult;
|
|
DrawText(caliperResult, cogCameraDisplay);
|
|
}
|
|
}
|
|
}
|
|
|
|
private static void DrawText(CaliperResult caliperResult, ICogCameraDisplay cogCameraDisplay) {
|
|
if (caliperResult != null) {
|
|
var msgs = new List<string>();
|
|
msgs.Add(string.Empty);
|
|
msgs.Add(string.Format("Width : {0:0.00} px", caliperResult.WidthPx));
|
|
msgs.Add(string.Format("Width : {0:0.00} mm", caliperResult.WidthMm));
|
|
cogCameraDisplay.AddTextList(
|
|
GraphicColors.PatternFoundOK, new ImagePoint(caliperResult.ImagePosition.X, caliperResult.ImagePosition.Y), msgs);
|
|
}
|
|
}
|
|
|
|
private static void DrawWidth(CogCaliperTool cogCaliperTool, ICogCameraDisplay cogCameraDisplay) {
|
|
if (CogMeasureCommon.IsEdgeFound(cogCaliperTool)) {
|
|
double positionFirstX = cogCaliperTool.Results.Edges[0].PositionX;
|
|
double positionFirstY = cogCaliperTool.Results.Edges[0].PositionY;
|
|
double positionSecondX = cogCaliperTool.Results.Edges[1].PositionX;
|
|
double positionSecondY = cogCaliperTool.Results.Edges[1].PositionY;
|
|
|
|
var positionFirst = new ImagePoint(positionFirstX, positionFirstY);
|
|
var positionSecond = new ImagePoint(positionSecondX, positionSecondY);
|
|
cogCameraDisplay.AddLine(GraphicColors.PatternFoundOK, positionFirst, positionSecond);
|
|
}
|
|
}
|
|
|
|
[Obsolete]
|
|
private static void DrawWidth(PatternResult patternResult, ICogCameraDisplay cogCameraDisplay) {
|
|
foreach (BaseResult baseResult in patternResult.Results) {
|
|
var caliperResult = baseResult as CaliperResult;
|
|
var startPoint = MathUtil.CalculateCenter(caliperResult.ImagePosition, caliperResult.ImagePositionSecond) as ImagePoint;
|
|
cogCameraDisplay.AddVectors(
|
|
GraphicColors.PatternFoundOK,
|
|
startPoint,
|
|
new List<ImagePoint>() { caliperResult.ImagePosition, caliperResult.ImagePositionSecond });
|
|
}
|
|
}
|
|
}
|
|
}
|