Files
HawkeyeVision/Hawkeye.VisionBuilder.Workflow/Operations/Simple/Blobs/TwoBlobsAlign.cs
2025-08-19 12:45:50 +02:00

125 lines
4.1 KiB
C#

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<string, object> dict)
{
base.Save(dict);
dict[nameof(Reference1)] = Reference1.ToString();
dict[nameof(Reference2)] = Reference2.ToString();
dict[nameof(DesiredAngle)] = DesiredAngle;
}
public override void Load(Dictionary<string, object> 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)]);
}
}