229 lines
8.7 KiB
C#
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);
|
|
}
|
|
}
|
|
}
|
|
}
|