using HalconDotNet; using Microsoft.ML.OnnxRuntime; using Microsoft.ML.OnnxRuntime.Tensors; using Newtonsoft.Json.Linq; using System; using System.Collections.Generic; using System.Drawing; using System.Drawing.Imaging; using System.IO; using System.Linq; using System.Reflection; using System.Text; using System.Threading; using System.Threading.Tasks; using Yolo5; namespace AssistClient.Device { public class SizeLib : IDisposable { public Action WarningEvent; /// /// 检测结果JSON(原图,结果) /// public Action finishEvent; /// /// 是否打开设备成功 /// public bool IsInit { get; private set; } = false; //private System.Timers.Timer timer = new System.Timers.Timer(); //配置 HDevEngine MyEngine = new HDevEngine(); private Thread t_task; public SizeLib() { } public bool start(string enginePath) { try { IsInit = true; taskList.Clear(); MyEngine.SetProcedurePath(enginePath); t_task = new System.Threading.Thread(run); t_task.IsBackground = true; t_task.Start(); return true; } catch (Exception ex) { WarningEvent?.Invoke(WarningEnum.High, ex.Message); return false; } } public void stop() { if (!IsInit) return; try { IsInit = false; //timer.Elapsed -= Timer_Elapsed; MyEngine.Dispose(); } catch { } } private bool _debug = false; public bool setDebug { get { return _debug; } set { if (!IsInit) return; _debug = value; if (_debug) MyEngine.StartDebugServer(); else MyEngine.StopDebugServer(); } } private void run() { int taskCount; while (IsInit) { lock (taskList) { taskCount = taskList.Count; } if (taskCount < 1) { Thread.Sleep(10); continue; } //// int step = 0; var task = pop(); try { if (task != null) { var Program1 = new HDevProcedure(task.engineName); HDevProcedureCall ProcCall1_PI_PT = new HDevProcedureCall(Program1); step = 1; // HObject image; if (task.bmp != null) Bitmap2HObjectBpp24(out image, task.bmp); else HOperatorSet.ReadImage(out image, task.file_path); step = 2; //设置外部函数输入 ProcCall1_PI_PT.SetInputIconicParamObject("Image_Repair", image); ProcCall1_PI_PT.SetInputCtrlParamTuple("Index", task.index);//参数0-9 ProcCall1_PI_PT.SetInputCtrlParamTuple("PoseX", task.posX); ProcCall1_PI_PT.SetInputCtrlParamTuple("PoseY", task.posY); ProcCall1_PI_PT.SetInputCtrlParamTuple("PoseMarkX_Detect_1", task.MarkPointList[0]); ProcCall1_PI_PT.SetInputCtrlParamTuple("PoseMarkY_Detect_1", task.MarkPointList[1]); ProcCall1_PI_PT.SetInputCtrlParamTuple("PoseMarkX_Detect_2", task.MarkPointList[2]); ProcCall1_PI_PT.SetInputCtrlParamTuple("PoseMarkY_Detect_2", task.MarkPointList[3]); ProcCall1_PI_PT.SetInputCtrlParamTuple("PoseMarkX_Detect_3", task.MarkPointList[4]); ProcCall1_PI_PT.SetInputCtrlParamTuple("PoseMarkY_Detect_3", task.MarkPointList[5]); ProcCall1_PI_PT.SetInputCtrlParamTuple("PoseMarkX_Detect_4", task.MarkPointList[6]); ProcCall1_PI_PT.SetInputCtrlParamTuple("PoseMarkY_Detect_4", task.MarkPointList[7]); step = 3; ProcCall1_PI_PT.Execute();//执行外部函数 step = 4; //获取外部函数输出 step = 5; task.isSucceed = true; task.resultInfo = "成功"; callback(task); } } catch (Exception ex) { WarningEvent?.Invoke(WarningEnum.Low, "SizeLib task err(" + step + "):" + ex.Message); task.isSucceed = false; task.resultInfo = $"(errcode:{step}):{ex.Message}"; callback(task); } } } private void callback(SizeTask task) { //返回成功/失败,异步调用 if (task.finishEvent != null || (task.finishEvent = finishEvent) != null) //task.finishEvent.BeginInvoke(result, errInfo, res => task.finishEvent.EndInvoke(res), null); System.Threading.ThreadPool.QueueUserWorkItem(waitCallback, task); } //异步回调 WaitCallback waitCallback = new WaitCallback(o => { var task = (SizeTask)o; task.finishEvent(task); }); //=======task list private List taskList = new List(); public class SizeTask { public int stepIndex;//库内部不用,回调时引用 public string engineName; /// /// 源文件 /// public string file_path; public double posX, posY; public Bitmap bmp; /// /// 比对(index=777); 计算Mark(111/222/333/444); 尺寸(0-9); 轴偏移调整(10,20,30...) /// public int index; //index=8 PT1=PT2 //MARK点 public double[] MarkPointList = { 0, 0, 0, 0, 0, 0, 0, 0 }; /// /// 完成后回调 /// public Action finishEvent; public long createTime = DateTime.Now.Ticks; //==结果返回 /// /// 比对结果(index=777) /// public bool CompResult; public double PT1, PT2, Shanxian, Circle_Ymm, Circle_Xmm, offsetX, offsetY; public bool isSucceed;//转换是否成功 public string resultInfo = "";//成功或失败信息 } public void add(SizeTask task) { lock (taskList) taskList.Add(task); } private SizeTask pop() { lock (taskList) { if (taskList.Count < 1) return null; int index = 0;// taskList.FindIndex(p => { return p.isSync; }); //if (index < 0) index = 0; var task = taskList[0]; taskList.RemoveAt(0); return task; } } public void Dispose() { stop(); } /// /// Bitmap转HObject灰度图 /// /// Bitmap图像 /// HObject图像 private void Bitmap2HObjectBpp8(out HObject image, Bitmap bmp) { try { Rectangle rect = new Rectangle(0, 0, bmp.Width, bmp.Height); BitmapData srcBmpData = bmp.LockBits(rect, ImageLockMode.ReadOnly, PixelFormat.Format8bppIndexed); HOperatorSet.GenImage1(out image, "byte", bmp.Width, bmp.Height, srcBmpData.Scan0); bmp.UnlockBits(srcBmpData); } catch (Exception) { image = null; } } public void Bitmap2HObjectBpp24(out HObject image, Bitmap bmp) { try { Rectangle rect = new Rectangle(0, 0, bmp.Width, bmp.Height); BitmapData srcBmpData = bmp.LockBits(rect, ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb); HOperatorSet.GenImageInterleaved(out image, srcBmpData.Scan0, "bgr", bmp.Width, bmp.Height, 0, "byte", 0, 0, 0, 0, -1, 0); bmp.UnlockBits(srcBmpData); } catch (Exception ex) { image = null; } } } }