2026-01-26 14:51:28 +09:00

229 lines
8.7 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.Blob;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Runtime.Serialization.Formatters.Binary;
namespace CogPattern {
/// <summary>
/// Blob 패턴 파라미터
/// </summary>
public class BlobRunParam : IRunParam, ICloneable {
internal BlobParamExt BlobParamExt { get; set; } = new BlobParamExt();
/// <summary>
/// 타겟 컬러
/// </summary>
public eForegroundColor ForegroundColor { get; set; } = eForegroundColor.White;
/// <summary>
/// 패턴 찾기 영역
/// </summary>
public ROI FindROI { get; set; } = new ROI();
/// <summary>
/// 파라미터 복제
/// </summary>
/// <returns>BlobRunParam</returns>
public object Clone() {
return new BlobRunParam() {
BlobParamExt = this.BlobParamExt.Clone() as BlobParamExt,
ForegroundColor = this.ForegroundColor,
FindROI = this.FindROI.Clone() as ROI,
};
}
/// <summary>
/// Blob 영역 픽셀 하한값 가져오기
/// </summary>
/// <returns>Blob 영역 픽셀 하한값</returns>
public double GetAreaLow() => BlobParamExt.AreaLow;
/// <summary>
/// Blob 영역 픽셀 상한값 가져오기
/// </summary>
/// <returns>Blob 영역 픽셀 상한값</returns>
public double GetAreaHigh() => BlobParamExt.AreaHigh;
/// <summary>
/// Blob 영역 상한값 및 하한값 타당성 체크
/// </summary>
/// <returns>Blob 영역 상한값 및 하한값 타당 여부</returns>
public bool IsValidRunParam() {
return BlobParamExt.AreaHigh > BlobParamExt.AreaLow;
}
}
internal static class CogBlob {
private static Logger _Logger = new Logger(typeof(CogBlob).Name);
public static CogBlobTool CreateTool() {
return new CogBlobTool();
}
public static CogBlobTool LoadTool(string filePath) {
return (CogBlobTool)CogSerializer.LoadObjectFromFile(
filePath,
typeof(BinaryFormatter),
CogSerializationOptionsConstants.Minimum);
}
public static int SaveTool(CogBlobTool cogBlobTool, string filePath) {
if (cogBlobTool != null && filePath != null) {
CogSerializer.SaveObjectToFile(
cogBlobTool,
filePath,
typeof(BinaryFormatter),
CogSerializationOptionsConstants.Minimum);
return E1.OK;
}
return E1.GENERIC;
}
public static void FreeTool(CogBlobTool cogBlobTool) {
if (cogBlobTool != null) {
cogBlobTool.Dispose();
cogBlobTool = null;
}
}
public static ROI GetFindROI(CogBlobTool cogBlobTool) {
if (cogBlobTool.Region == null) {
return new ROI();
}
return CogEnvironment.ConvertToRoi(cogBlobTool.Region as CogRectangleAffine);
}
public static int SetFindROI(CogBlobTool cogBlobTool, ROI findRoi) {
if (findRoi.Width > 0 && findRoi.Height > 0) {
if (cogBlobTool != null) {
cogBlobTool.Region = CogEnvironment.ConvertToCogRectangleAffine(findRoi);
}
}
return E1.OK;
}
public static int SetRunParam(CogBlobTool cogBlobTool, IRunParam runParam) {
if (runParam is BlobRunParam) {
var param = runParam as BlobRunParam;
if (cogBlobTool != null) {
//cogBlobTool.InputImage = image; // Find시 넣어주기로 함.
cogBlobTool.RunParams.SegmentationParams.Polarity = GetBlobPolarity(param.ForegroundColor);
cogBlobTool.Region = CogEnvironment.ConvertToCogRectangleAffine(param.FindROI);
cogBlobTool.RunParams.ConnectivityMinPixels = Convert.ToInt32(param.BlobParamExt.AreaLow);
}
return E1.OK;
}
return E1.GENERIC;
}
private static CogBlobSegmentationPolarityConstants GetBlobPolarity(eForegroundColor color) {
if (color == eForegroundColor.White) {
return CogBlobSegmentationPolarityConstants.LightBlobs;
}
else {
return CogBlobSegmentationPolarityConstants.DarkBlobs;
}
}
public static PatternResult Find(CogBlobTool cogBlobTool, ICogImage image, ROI findRoi, BlobParamExt paramExt) {
if (CogEnvironment.IsColorImage(image)) {
var grayImage = CogEnvironment.ConvertToGray(image);
var patternResult = FindInternal(cogBlobTool, grayImage, findRoi, paramExt);
CogEnvironment.FreeImage(grayImage);
return patternResult;
}
return FindInternal(cogBlobTool, image, findRoi, paramExt);
}
private static PatternResult FindInternal(CogBlobTool cogBlobTool, ICogImage image, ROI findRoi, BlobParamExt paramExt) {
var timeFind = new Stopwatch();
timeFind.Start();
PatternResult finderResult;
cogBlobTool.InputImage = image;
if (!ROI.IsNullOrEmpty(findRoi)) {
cogBlobTool.Region = CogEnvironment.ConvertToCogRectangleAffine(findRoi);
}
cogBlobTool.Run();
finderResult = ExtractResults(cogBlobTool, paramExt);
timeFind.Stop();
finderResult.TactTimeInMilliSec = timeFind.ElapsedMilliseconds;
return finderResult;
}
private static PatternResult ExtractResults(CogBlobTool cogBlobTool, BlobParamExt paramExt) {
List<BlobResult> results = new List<BlobResult>();
CogBlobResultCollection cogBlobResults = cogBlobTool.Results.GetBlobs();
foreach (CogBlobResult result in cogBlobResults) {
if (result.Area > paramExt.AreaLow) {
if (result.Area < paramExt.AreaHigh) {
_Logger.FuncI($"Area : {result.Area}, AreaLow : {paramExt.AreaLow}, AreaHigh : {paramExt.AreaHigh} ");
var position = new ImagePoint(result.CenterOfMassX, result.CenterOfMassY);
results.Add(new BlobResult(
position,
new ImagePoint(),
result.Area));
}
}
}
return new PatternResult() {
Status = (results.Count > 0) ? eFoundStatus.FoundOK : eFoundStatus.NotFound,
Results = results
};
}
public static PatternResult GetNotFoundPatternResult() {
return new PatternResult() {
Status = eFoundStatus.NotFound,
Results = new List<BlobResult>()
};
}
public static void Draw(PatternResult patternResult, ICogCameraDisplay cogCameraDisplay) {
if (patternResult.Status == eFoundStatus.FoundOK) {
var results = patternResult.Results as List<BlobResult>;
var color = GraphicColors.GetFindResultColor(patternResult.Status, isFixturePattern: false);
var crosses = new List<Cross>();
foreach (var result in results) {
var cross = new Cross(result.ImagePosition.Clone() as ImagePoint, 50);
crosses.Add(cross);
cogCameraDisplay.SetPatternTracking(cross);
cogCameraDisplay.AddCross(cross, color);
var msgs = new List<string>();
msgs.Add(string.Format("I({0:0.0}, {1:0.0})", result.ImagePosition.X, result.ImagePosition.Y));
msgs.Add(result.ConvertMaterialPosition());
msgs.Add(string.Format("Area : {0:0.00}", result.Area));
msgs.Add(string.Format("TactTime : {0} ms", Math.Round(patternResult.TactTimeInMilliSec)));
msgs.Add(string.Format("ID : {0}_{1}", patternResult.PatternIndex.PatternId, patternResult.PatternIndex.PatternSubId));
cogCameraDisplay.AddTextList(
color, new ImagePoint(result.ImagePosition.X, result.ImagePosition.Y), msgs);
}
cogCameraDisplay.DrawPatternTrackings(crosses);
}
}
}
}