using System;
using System.Collections.Generic;
using System.Threading;
using HalconDotNet;
using TeamAAS.FlowEditor.Models;
using TeamAAS.FlowEditor.Plugins;
using Plugins.Halcon.Models;
using Plugins.Halcon;
namespace Plugins.Halcon
{
// ─────────────────────────────────────────────────────────────────────
// HALCON 图像处理分类算子(从主程序集迁入分类 DLL)。
// 显示名/类型全名保持不变 —— 工具箱、流程文件、公式绑定全部兼容。
// ─────────────────────────────────────────────────────────────────────
/// H阈值分割:提取灰度落在 [最小,最大] 区间的像素为区域。
[Serializable]
[Plugin("H阈值分割", PluginCategory.Halocn模块, typeof(HalconThresholdModel), "FilterOutline",
NodeShape = NodeCategory.Normal, IsSubFlowNode = true, VisionCategory = VisionPlugin.图像处理,
Description = "灰度阈值分割:把灰度∈[最小,最大]的像素提取为区域")]
public class HalconThresholdPlugin : BasePlugin
{
public override List DeclareOutputs() => new List
{
new OutputField("区域", typeof(object)),
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; }
bool owned = false;
HObject image = null;
try
{
var src = GetResolve(Model.ImageSource);
if (src == null) return Fail("未获取到输入图像(请绑定「输入图像」,例如 &{输入.图像})");
owned = !(src is HObject);
image = HalconRuntime.ToHObject(src);
Log(3, $"阈值分割:灰度区间[{Model.MinGray}, {Model.MaxGray}]");
var region = HalconRuntime.Threshold(image, Model.MinGray, Model.MaxGray);
res["区域"] = region;
res["结果"] = true;
HalconEditorPreview.Show(Model, src, region, "red"); // 图层发布 + 编辑器预览:底图 + 阈值区域叠加
Log(2, $"阈值分割完成,区域对象数={HalconRuntime.CountObj(region)}");
return NodeRunStatus.Success;
}
catch (Exception ex) { return Fail(ex.Message); }
finally { if (owned) HalconRuntime.Dispose(image); }
}
}
/// H连通域:把一个区域拆成互不相连的多个独立区域。
[Serializable]
[Plugin("H连通域", PluginCategory.Halocn模块, typeof(HalconConnectionModel), "VectorSquare",
NodeShape = NodeCategory.Normal, IsSubFlowNode = true, VisionCategory = VisionPlugin.图像处理,
Description = "连通域拆分:把一个区域拆成多个独立区域,输出区域集与数量")]
public class HalconConnectionPlugin : BasePlugin
{
public override List DeclareOutputs() => new List
{
new OutputField("区域集", typeof(object)),
new OutputField("数量", typeof(int)),
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("未获取到输入区域(请绑定上游「区域」输出)");
var connected = HalconRuntime.Connection(region);
int n = HalconRuntime.CountObj(connected);
res["区域集"] = connected;
res["数量"] = n;
res["结果"] = true;
HalconEditorPreview.Show(Model, null, connected, "yellow"); // 只更新叠加区域,保留底图
Log(2, $"连通域拆分完成,得到 {n} 个独立区域");
return NodeRunStatus.Success;
}
catch (Exception ex) { return Fail(ex.Message); }
}
}
/// H图像预处理:滤波 / 灰度线性变换 / 转灰度。
[Serializable]
[Plugin("H图像预处理", PluginCategory.Halocn模块, typeof(HalconPreprocessModel), "Blur",
NodeShape = NodeCategory.Normal, IsSubFlowNode = true, VisionCategory = VisionPlugin.图像处理,
Description = "图像预处理:均值/中值/高斯滤波、灰度线性变换、转灰度")]
public class HalconPreprocessPlugin : BasePlugin
{
public override List DeclareOutputs() => new List
{
new OutputField("图像", typeof(object)),
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; }
bool owned = false;
HObject image = null;
try
{
var src = GetResolve(Model.ImageSource);
if (src == null) return Fail("未获取到输入图像(请绑定「输入图像」)");
owned = !(src is HObject);
image = HalconRuntime.ToHObject(src);
HObject outImg;
switch (Model.ProcessType)
{
case HalconPreprocessType.均值滤波:
outImg = HalconRuntime.MeanImage(image, Model.Param1, Model.Param2 > 0 ? Model.Param2 : Model.Param1);
break;
case HalconPreprocessType.中值滤波:
outImg = HalconRuntime.MedianImage(image, "circle", Model.Param1, "mirrored");
break;
case HalconPreprocessType.高斯滤波:
outImg = HalconRuntime.GaussFilter(image, Model.Param1);
break;
case HalconPreprocessType.灰度线性变换:
outImg = HalconRuntime.ScaleImage(image, Model.Param1, Model.Param2);
break;
case HalconPreprocessType.转灰度:
outImg = HalconRuntime.RgbToGray(image);
break;
default:
return Fail($"未知处理方式:{Model.ProcessType}");
}
res["图像"] = outImg;
res["结果"] = true;
HalconEditorPreview.Show(Model, outImg, null); // 图层发布:处理后的图像作底图
Log(2, $"图像预处理完成:{Model.ProcessType}");
return NodeRunStatus.Success;
}
catch (Exception ex) { return Fail(ex.Message); }
finally { if (owned) HalconRuntime.Dispose(image); }
}
}
/// H形态学:对区域做膨胀/腐蚀/开/闭运算。
[Serializable]
[Plugin("H形态学", PluginCategory.Halocn模块, typeof(HalconMorphologyModel), "ArrowExpandAll",
NodeShape = NodeCategory.Normal, IsSubFlowNode = true, VisionCategory = VisionPlugin.图像处理,
Description = "形态学:膨胀/腐蚀/开运算/闭运算(圆形结构元)")]
public class HalconMorphologyPlugin : BasePlugin
{
public override List DeclareOutputs() => new List
{
new OutputField("区域", typeof(object)),
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("未获取到输入区域(请绑定上游「区域」输出)");
HObject outRegion;
switch (Model.Operation)
{
case HalconMorphOperation.膨胀: outRegion = HalconRuntime.DilationCircle(region, Model.Radius); break;
case HalconMorphOperation.腐蚀: outRegion = HalconRuntime.ErosionCircle(region, Model.Radius); break;
case HalconMorphOperation.开运算: outRegion = HalconRuntime.OpeningCircle(region, Model.Radius); break;
case HalconMorphOperation.闭运算: outRegion = HalconRuntime.ClosingCircle(region, Model.Radius); break;
default: return Fail($"未知形态学操作:{Model.Operation}");
}
res["区域"] = outRegion;
res["结果"] = true;
HalconEditorPreview.Show(Model, null, outRegion, "orange"); // 只更新叠加区域,保留底图
Log(2, $"形态学完成:{Model.Operation},半径={Model.Radius}");
return NodeRunStatus.Success;
}
catch (Exception ex) { return Fail(ex.Message); }
}
}
}