2026-01-26 18:56:53 +09:00

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 });
}
}
}
}