using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using HalconDotNet;
using TeamAAS.FlowEditor.Models;
using TeamAAS.FlowEditor.Plugins;
using Plugins.Halcon.Models;
namespace Plugins.Halcon
{
// ─────────────────────────────────────────────────────────────────────
// HALCON 几何测量分类算子(从主程序集迁入分类 DLL)。
// 显示名/类型全名保持不变 —— 工具箱、流程文件、公式绑定全部兼容。
// ─────────────────────────────────────────────────────────────────────
/// H区域特征:面积、重心、区域数量。
[Serializable]
[Plugin("H区域特征", PluginCategory.Halocn模块, typeof(HalconAreaCenterModel), "Ruler",
NodeShape = NodeCategory.Normal, IsSubFlowNode = true, VisionCategory = VisionPlugin.几何测量,
Description = "区域特征:面积、重心、数量(区域集时给出总面积与首个区域重心)")]
public class HalconAreaCenterPlugin : BasePlugin
{
public override List DeclareOutputs() => new List
{
new OutputField("数量", typeof(int)),
new OutputField("总面积", typeof(double)),
new OutputField("重心行", typeof(double)),
new OutputField("重心列", typeof(double)),
new OutputField("结果", typeof(bool)),
};
public override NodeRunStatus PluginRun(CancellationToken token, out Dictionary results)
{
var res = new Dictionary();
results = res;
NodeRunStatus Fail(string m) { res["Error"] = m; res["结果"] = false; Log(1, $"区域特征失败: {m}", TeamAAS.LogLevel.Error); return NodeRunStatus.Failed; }
try
{
var src = GetResolve(Model.RegionSource);
if (!(src is HObject region)) return Fail("未获取到输入区域(请绑定上游「区域」输出)");
HalconRuntime.AreaCenter(region, out double[] areas, out double[] rows, out double[] cols);
int count = areas.Length;
double total = areas.Length > 0 ? areas.Sum() : 0d;
double row = rows.Length > 0 ? rows[0] : 0d;
double col = cols.Length > 0 ? cols[0] : 0d;
res["数量"] = count;
res["总面积"] = total;
res["重心行"] = row;
res["重心列"] = col;
res["结果"] = true;
Log(2, $"区域特征:数量={count},总面积={total:F1},首区域重心=({row:F1},{col:F1})");
return NodeRunStatus.Success;
}
catch (Exception ex) { return Fail(ex.Message); }
}
}
/// H外接矩形:区域的最小外接正矩形边界与宽高。
[Serializable]
[Plugin("H外接矩形", PluginCategory.Halocn模块, typeof(HalconRectangleModel), "CropFree",
NodeShape = NodeCategory.Normal, IsSubFlowNode = true, VisionCategory = VisionPlugin.几何测量,
Description = "最小外接正矩形:行1/列1/行2/列2 与 宽/高(取第一个区域)")]
public class HalconRectanglePlugin : BasePlugin
{
public override List DeclareOutputs() => new List
{
new OutputField("行1", typeof(double)),
new OutputField("列1", typeof(double)),
new OutputField("行2", typeof(double)),
new OutputField("列2", typeof(double)),
new OutputField("宽", typeof(double)),
new OutputField("高", typeof(double)),
new OutputField("结果", typeof(bool)),
};
public override NodeRunStatus PluginRun(CancellationToken token, out Dictionary results)
{
var res = new Dictionary();
results = res;
NodeRunStatus Fail(string m) { res["Error"] = m; res["结果"] = false; Log(1, $"外接矩形失败: {m}", TeamAAS.LogLevel.Error); return NodeRunStatus.Failed; }
try
{
var src = GetResolve(Model.RegionSource);
if (!(src is HObject region)) return Fail("未获取到输入区域(请绑定上游「区域」输出)");
HalconRuntime.SmallestRectangle1(region, out double r1, out double c1, out double r2, out double c2);
res["行1"] = r1;
res["列1"] = c1;
res["行2"] = r2;
res["列2"] = c2;
res["宽"] = c2 - c1;
res["高"] = r2 - r1;
res["结果"] = true;
Log(2, $"外接矩形:({r1:F1},{c1:F1})-({r2:F1},{c2:F1}),宽={c2 - c1:F1},高={r2 - r1:F1}");
return NodeRunStatus.Success;
}
catch (Exception ex) { return Fail(ex.Message); }
}
}
}
namespace Plugins.Halcon.Models
{
using PropertyGridLib.Attributes;
using PropertyGridLib.Controls;
using System.ComponentModel;
using TeamAAS.FlowEditor.Plugins;
using TeamAAS.FlowEngine.FormulaData;
/// 区域特征:面积、重心、区域数量。
[Serializable]
public class HalconAreaCenterModel : HalconOperatorModelBase
{
[Category("I.输入")]
[DisplayName("1.输入区域")]
[Description("上游区域(单个或区域集;区域集时给出总面积与首个区域重心)")]
[FormulaEditor(typeof(PluginDataProvider))]
public FormulaBound