/* * 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 { /// /// Blob 패턴 파라미터 /// public class BlobRunParam : IRunParam, ICloneable { internal BlobParamExt BlobParamExt { get; set; } = new BlobParamExt(); /// /// 타겟 컬러 /// public eForegroundColor ForegroundColor { get; set; } = eForegroundColor.White; /// /// 패턴 찾기 영역 /// public ROI FindROI { get; set; } = new ROI(); /// /// 파라미터 복제 /// /// BlobRunParam public object Clone() { return new BlobRunParam() { BlobParamExt = this.BlobParamExt.Clone() as BlobParamExt, ForegroundColor = this.ForegroundColor, FindROI = this.FindROI.Clone() as ROI, }; } /// /// Blob 영역 픽셀 하한값 가져오기 /// /// Blob 영역 픽셀 하한값 public double GetAreaLow() => BlobParamExt.AreaLow; /// /// Blob 영역 픽셀 상한값 가져오기 /// /// Blob 영역 픽셀 상한값 public double GetAreaHigh() => BlobParamExt.AreaHigh; /// /// Blob 영역 상한값 및 하한값 타당성 체크 /// /// Blob 영역 상한값 및 하한값 타당 여부 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 results = new List(); 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() }; } public static void Draw(PatternResult patternResult, ICogCameraDisplay cogCameraDisplay) { if (patternResult.Status == eFoundStatus.FoundOK) { var results = patternResult.Results as List; var color = GraphicColors.GetFindResultColor(patternResult.Status, isFixturePattern: false); var crosses = new List(); 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(); 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); } } } }