using Hawkeye.VisionBuilder.Workflow.Datatypes; using Hawkeye.VisionBuilder.Workflow.Datatypes.Elements.Align; using Hawkeye.VisionBuilder.Workflow.Datatypes.Elements.Origin; using Hawkeye.VisionBuilder.Workflow.Links; using Hawkeye.VisionBuilder.Workflow.Operations.Attributes; using OpenCvSharp; namespace Hawkeye.VisionBuilder.Workflow.Operations; [Category("Simple/Blobs")] public class TwoBlobsAlign:BaseOperation,IHaveOrigin { private readonly WorkflowList _workflowList; public TwoBlobsAlign(WorkflowList workflowList) { _workflowList = workflowList; } public Guid Reference1 { get; set; } = NoOrigin.Instance.Id; public Guid Reference2 { get; set; } = NoOrigin.Instance.Id; public int DesiredAngle { get; set; } [NotForTool] public OriginElement Origin { get; private set; } = OriginElement.Default; private string _status; protected override void InterpretInternal(Context context) { var reference1 = _workflowList.GetOriginById(Reference1); var reference2 = _workflowList.GetOriginById(Reference2); if (reference1 == NoOrigin.Instance) { _status = $"{nameof(Reference1)} must be set"; Result = false; return; } if (reference2 == NoOrigin.Instance) { _status = $"{nameof(Reference2)} must be set"; Result = false; return; } if (!(reference1 as BaseOperation).Result) { _status = $"{nameof(Reference1)} detection failed"; Result = false; return; } if (!(reference2 as BaseOperation).Result) { _status = $"{nameof(Reference2)} detection failed"; Result = false; return; } if (context.ActiveImage == null) { _status = $"Image required"; Result = false; return; } var center = (reference1.Origin.Location + reference2.Origin.Location) / 2; var deltaX = reference2.Origin.Location.X-reference1.Origin.Location.X; var deltaY = reference2.Origin.Location.Y-reference1.Origin.Location.Y; var angle = ((float)Math.Atan2(deltaY, deltaX))/MathF.PI*180f; var deltaAngle = DesiredAngle - angle; var matrix=Cv2.GetRotationMatrix2D(new Point2f(center.X, center.Y), -deltaAngle, 1); var destImage = new Mat(context.ActiveImage.ImageData.Size(), context.ActiveImage.ImageData.Type()); Cv2.WarpAffine(context.ActiveImage.ImageData, destImage,matrix,destImage.Size()); context.ActiveImage=new HawkeyeImage(){Filename = context.ActiveImage.Filename,ImageData = destImage }; Origin = new OriginElement() {Location = center }; _status = center.ToString(); Result = true; context.GraphicsElements.Add(new AlignElement(){Location = center}); } public override string ToString() { return _status; } public override void Save(BinaryWriter bw) { base.Save(bw); bw.Write(Reference1.ToString()); bw.Write(Reference2.ToString()); bw.Write(DesiredAngle); } public override void Load(BinaryReader br) { base.Load(br); Reference1 = new Guid(br.ReadString()); Reference2 = new Guid(br.ReadString()); DesiredAngle = br.ReadInt32(); } public override void Save(Dictionary dict) { base.Save(dict); dict[nameof(Reference1)] = Reference1.ToString(); dict[nameof(Reference2)] = Reference2.ToString(); dict[nameof(DesiredAngle)] = DesiredAngle; } public override void Load(Dictionary dict) { base.Load(dict); if (dict.ContainsKey(nameof(Reference1))) Reference1 = new Guid(dict[nameof(Reference1)].ToString()); if (dict.ContainsKey(nameof(Reference2))) Reference2 = new Guid(dict[nameof(Reference2)].ToString()); if (dict.ContainsKey(nameof(DesiredAngle))) DesiredAngle = Convert.ToInt32(dict[nameof(DesiredAngle)]); } }