using Hawkeye.VisionBuilder.Workflow.Datatypes.Elements.Origin; using Hawkeye.VisionBuilder.Workflow.Datatypes.Elements.Rectangle; using Hawkeye.VisionBuilder.Workflow.Operations.Attributes; using OpenCvSharp; using System; using System.Security.Cryptography.Xml; using Point = OpenCvSharp.Point; namespace Hawkeye.VisionBuilder.Workflow.Operations; [Category("Simple/Blobs")] public class FindRectangleOperation:BaseOperation { private readonly WorkflowList _workflowList; public int MinWidth { get; set; } public int MaxWidth { get; set; } = 999999; public int MinHeight { get; set; } public int MaxHeight { get; set; } = 999999; public Guid ReferenceId { get; set; } = new Guid(); public bool BadIfFound { get; set; }=false; public FindRectangleOperation(WorkflowList workflowList) { _workflowList = workflowList; SearchArea = new RectangleElement() { Editable = true, Location = Vector2.One * 100, Size = Vector2.One * 100, IsGood = true }; } public RectangleElement SearchArea { get; set; } //processing result of current element [NotForTool] public OriginElement Origin { get; private set; } = OriginElement.Default; protected override void InterpretInternal(Context context) { if(!CheckImageExists(context)) return; SearchArea.MovePivot(_workflowList.GetOriginById(ReferenceId).Origin.Location); var image = context.ActiveImage.ImageData; var mat = new Mat(image.Size(), image.Type(), Scalar.Black); SearchArea.FillMat(mat); var contoursMat = image.BitwiseAnd(mat).ToMat(); context.GraphicsElements.Add(SearchArea); // find rectangle on image Cv2.FindContours(contoursMat, out var contours, out _, RetrievalModes.External, ContourApproximationModes.ApproxSimple); foreach (Point[] contour in contours) { var rect = Cv2.BoundingRect(contour); if (rect.Width >= MinWidth && rect.Width <= MaxWidth && rect.Height >= MinHeight && rect.Height <= MaxHeight) { Status = "Rectangle: " + rect; Result = !BadIfFound; RectangleElement re = new RectangleElement() { Editable = false, IsGood = !BadIfFound, Location = new Vector2(rect.X, rect.Y), Size = new Vector2(rect.Width, rect.Height) }; context.GraphicsElements.Add(re); return; } } Status = "No rectangle found"; Result = BadIfFound; } public override void SetParameters(Dictionary parameters) { base.SetParameters(parameters); SearchArea.SetPivot(_workflowList.GetOriginById(ReferenceId).Origin.Location); } public override void Save(BinaryWriter bw) { base.Save(bw); bw.Write(ReferenceId.ToString()); bw.Write(MinWidth); bw.Write(MaxWidth); bw.Write(MinHeight); bw.Write(MaxHeight); bw.Write(BadIfFound); SearchArea.Save(bw); } public override void Load(BinaryReader br) { base.Load(br); ReferenceId = new Guid(br.ReadString()); MinWidth = br.ReadInt32(); MaxWidth = br.ReadInt32(); MinHeight = br.ReadInt32(); MaxHeight = br.ReadInt32(); BadIfFound = br.ReadBoolean(); SearchArea.Load(br); } }