HalconEdgeNodes.cs 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Threading;
  4. using HalconDotNet;
  5. using TeamAAS.FlowEditor.Execution;
  6. using TeamAAS.FlowEditor.Models;
  7. using TeamAAS.FlowEditor.Plugins;
  8. using Plugins.Halcon.Models;
  9. using Plugins.Halcon;
  10. namespace Plugins.Halcon
  11. {
  12. // ─────────────────────────────────────────────────────────────────────
  13. // HALCON 检测识别分类算子(新增)。
  14. // ─────────────────────────────────────────────────────────────────────
  15. /// <summary>H边缘提取:Sobel 梯度 + 阈值,输出边缘区域(可配合形状筛选取感兴趣边缘)。</summary>
  16. [Serializable]
  17. [Plugin("H边缘提取", PluginCategory.Halocn模块, typeof(HalconEdgeModel), "VectorLine",
  18. NodeShape = NodeCategory.Normal, IsSubFlowNode = true, VisionCategory = VisionPlugin.检测识别,
  19. Description = "Sobel 边缘提取:梯度幅值 + 灰度阈值 → 边缘区域;高级编辑可加载图像调试")]
  20. public class HalconEdgePlugin : BasePlugin<HalconEdgeModel>
  21. {
  22. public override List<OutputField> DeclareOutputs() => new List<OutputField>
  23. {
  24. new OutputField("边缘区域", typeof(object)),
  25. new OutputField("结果", typeof(bool)),
  26. };
  27. public override NodeRunStatus PluginRun(CancellationToken token, out Dictionary<string, object> results)
  28. {
  29. var res = new Dictionary<string, object>();
  30. results = res;
  31. NodeRunStatus Fail(string m) { res["Error"] = m; res["结果"] = false; Log(1, $"边缘提取失败: {m}", TeamAAS.LogLevel.Error); return NodeRunStatus.Failed; }
  32. bool owned = false;
  33. HObject image = null;
  34. HObject edgeAmp = null;
  35. try
  36. {
  37. var src = GetResolve(Model.ImageSource);
  38. if (src == null) return Fail("未获取到输入图像(请绑定「输入图像」,例如 &{输入.图像})");
  39. owned = !(src is HObject);
  40. image = HalconRuntime.ToHObject(src);
  41. Log(3, $"边缘提取:Sobel[{Model.FilterType}] 孔径={Model.ApertureSize},阈值[{Model.MinGray},{Model.MaxGray}]");
  42. HOperatorSet.SobelAmp(image, out edgeAmp, Model.FilterType, Model.ApertureSize);
  43. var edges = HalconRuntime.Threshold(edgeAmp, Model.MinGray, Model.MaxGray);
  44. res["边缘区域"] = edges;
  45. res["结果"] = true;
  46. HalconEditorPreview.Show(Model, src, edges, "green"); // 底图 + 边缘叠加
  47. Log(2, $"边缘提取完成:区域对象数={HalconRuntime.CountObj(edges)}");
  48. return NodeRunStatus.Success;
  49. }
  50. catch (Exception ex) { return Fail(ex.Message); }
  51. finally
  52. {
  53. if (edgeAmp != null) { try { edgeAmp.Dispose(); } catch { } }
  54. if (owned) HalconRuntime.Dispose(image);
  55. }
  56. }
  57. }
  58. }
  59. namespace Plugins.Halcon.Models
  60. {
  61. using PropertyGridLib.Attributes;
  62. using PropertyGridLib.Controls;
  63. using System.ComponentModel;
  64. using TeamAAS.FlowEditor.Plugins;
  65. using TeamAAS.FlowEngine.FormulaData;
  66. /// <summary>边缘提取模型。</summary>
  67. [Serializable]
  68. public class HalconEdgeModel : HalconOperatorModelBase
  69. {
  70. [Category("I.输入")]
  71. [DisplayName("1.输入图像")]
  72. [Description("上游图像(GenImage/HObject)。子流程内通常绑定 &{输入.图像}")]
  73. [FormulaEditor(typeof(PluginDataProvider))]
  74. public FormulaBound<object> ImageSource { get; set; } = new FormulaBound<object>();
  75. [Category("II.参数")]
  76. [DisplayName("1.滤波类型")]
  77. [Description("Sobel 算子组合方式:sum_abs(常用)/sum_sqrt/sum_col/sum_row")]
  78. public string FilterType { get; set; } = "sum_abs";
  79. [Category("II.参数")]
  80. [DisplayName("2.孔径尺寸")]
  81. [Description("Sobel 滤波核尺寸(奇数):3/5/7,越大抗噪越强、定位越粗")]
  82. public int ApertureSize { get; set; } = 3;
  83. [Category("II.参数")]
  84. [DisplayName("3.最小梯度")]
  85. [Description("梯度阈值下限(含),低于此梯度不视为边缘")]
  86. public int MinGray { get; set; } = 30;
  87. [Category("II.参数")]
  88. [DisplayName("4.最大梯度")]
  89. [Description("梯度阈值上限(含)")]
  90. public int MaxGray { get; set; } = 255;
  91. }
  92. }