| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175 |
- using System;
- using System.Globalization;
- using System.IO;
- using System.Threading.Tasks;
- using System.Windows;
- using Cognex.VisionPro;
- using Cognex.VisionPro.ToolBlock;
- using Plugins.Vpp.Converters;
- using Plugins.Vpp.Views;
- using TeamAAS.Camera.Images;
- using TeamAAS.Vision;
- using TeamAAS.Vision.Calibration.Interfaces;
- namespace Plugins.Vpp.Engines
- {
- /// <summary>
- /// VisionPro 引擎:基于 UCDispVpp 多画面控件(VppWindow 网格 + 双击放大)。
- /// 实现 TeamAAS.Vision.IVisualEngine 抽象契约;引擎 SDK(Cognex)只被本插件引用。
- /// 同时实现 <see cref="ICalibrationVisionProvider"/>:为标定算法提供"给图取特征点"能力,
- /// 通过一个 Cognex <see cref="CogToolBlock"/>(约定输入 InputImage、输出 Found/Point)完成。
- /// </summary>
- public class VisionProEngine : IVisualEngine, ICalibrationVisionProvider
- {
- public string EngineName => "VisionPro9.0";
- // 标定工具(Cognex ToolBlock)与其持久化引用(.vpp 路径)。
- private CogToolBlock _calibTool;
- private string _toolRef;
- public FrameworkElement GetMainView()
- {
- return UCDispVpp.Instance;
- }
- public void ApplyHomeLayout(int frameCount, int arrange)
- {
- // RowColNumber:{画面总数, 排列方式}——内部按最优行列铺设 VppWindow 网格
- // frameCount=0 时清空画面区(主页面不显示画面框)
- UCDispVpp.Instance.RowColNumber = new[] { frameCount, arrange };
- }
- public FrameworkElement GetCalibrationView()
- {
- return new VppCalibrationPage();
- }
- /// <summary>设置指定画面框的标题(画面名称);index 越界时静默忽略。</summary>
- public void SetFrameCaption(int index, string name)
- {
- if (index < 0 || UCDispVpp.Instance.vppWindow.Count <= index) return;
- UCDispVpp.Instance.vppWindow[index].SetCaption(name);
- }
- /// <summary>设置指定画面框的状态圆点显隐;index 越界时静默忽略。</summary>
- public void SetFrameDotVisible(int index, bool visible)
- {
- if (index < 0 || UCDispVpp.Instance.vppWindow.Count <= index) return;
- UCDispVpp.Instance.vppWindow[index].SetStatusDotVisible(visible);
- }
- #region ICalibrationVisionProvider
- /// <summary>当前标定工具句柄(Cognex CogToolBlock)。</summary>
- public object CurrentTool => _calibTool;
- /// <summary>标定工具持久化引用(.vpp 路径)。</summary>
- public string ToolRef
- {
- get { return _toolRef; }
- set { _toolRef = value; }
- }
- /// <summary>
- /// 在图像上运行标定 ToolBlock,返回特征点像素坐标。
- /// 约定:ToolBlock 输入终端 "InputImage",输出终端 "Found"(bool)、"Point"(字符串 "x,y[,angle]")。
- /// </summary>
- public Task<(bool found, double px, double py, double angle)> FindCalibPoint(GenImage image)
- {
- return Task.Run(() =>
- {
- try
- {
- if (_calibTool == null || image == null) return (false, 0d, 0d, 0d);
- ICogImage cog = GenImageConverter.ToCogImage(image);
- if (cog == null) return (false, 0d, 0d, 0d);
- var input = _calibTool.Inputs["InputImage"];
- if (input != null) input.Value = cog;
- _calibTool.Run();
- CogToolBlockTerminalCollection outputs = _calibTool.Outputs;
- var foundTerminal = outputs["Found"];
- bool found = foundTerminal != null && foundTerminal.Value != null && Convert.ToBoolean(foundTerminal.Value);
- if (!found) return (false, 0d, 0d, 0d);
- double px = 0, py = 0, angle = 0;
- var pointTerminal = outputs["Point"];
- if (pointTerminal != null && pointTerminal.Value != null)
- {
- ParsePoint(pointTerminal.Value, ref px, ref py, ref angle);
- }
- return (true, px, py, angle);
- }
- catch
- {
- return (false, 0d, 0d, 0d);
- }
- });
- }
- /// <summary>畸变校正:VisionPro 引擎暂原样返回(如需棋盘格校正后续在此接入)。</summary>
- public Task<GenImage> Undistort(GenImage image)
- {
- return Task.FromResult(image);
- }
- /// <summary>从 .vpp 引用加载标定 ToolBlock;引用为空或加载失败时新建空 ToolBlock。</summary>
- public void LoadTool(string toolRef)
- {
- _toolRef = toolRef;
- _calibTool = null;
- try
- {
- if (!string.IsNullOrEmpty(toolRef) && File.Exists(toolRef))
- {
- _calibTool = CogSerializer.LoadObjectFromFile(toolRef) as CogToolBlock;
- }
- }
- catch
- {
- _calibTool = null;
- }
- if (_calibTool == null) _calibTool = new CogToolBlock();
- }
- /// <summary>将当前标定 ToolBlock 保存到目录下的 CalibTool.vpp,返回该路径作为持久化引用。</summary>
- public string SaveTool(string directory)
- {
- if (_calibTool == null) return _toolRef;
- try
- {
- if (!Directory.Exists(directory)) Directory.CreateDirectory(directory);
- string path = Path.Combine(directory, "CalibTool.vpp");
- CogSerializer.SaveObjectToFile(_calibTool, path);
- _toolRef = path;
- return path;
- }
- catch
- {
- return _toolRef;
- }
- }
- private static void ParsePoint(object value, ref double px, ref double py, ref double angle)
- {
- string s = value.ToString();
- if (string.IsNullOrWhiteSpace(s)) return;
- string[] items = s.Split(',');
- if (items.Length >= 2
- && double.TryParse(items[0].Trim(), NumberStyles.Float, CultureInfo.InvariantCulture, out double x)
- && double.TryParse(items[1].Trim(), NumberStyles.Float, CultureInfo.InvariantCulture, out double y))
- {
- px = x; py = y;
- }
- if (items.Length >= 3
- && double.TryParse(items[2].Trim(), NumberStyles.Float, CultureInfo.InvariantCulture, out double a))
- {
- angle = a;
- }
- }
- #endregion
- }
- }
|