using HalconDotNet; using Microsoft.ML.OnnxRuntime; using Microsoft.ML.OnnxRuntime.Tensors; using Newtonsoft.Json; using Newtonsoft.Json.Linq; using OpenCvSharp; 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 ProductionControl.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(); //777时用 Yolo_Class yolo5 =new Yolo_Class(); 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(); } } //流程:111,222,444,333,777,777,777,。。。 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; //设置外部函数输入 //if (task.index < 100) { ProcCall1_PI_PT.SetInputIconicParamObject("Image1", image.Clone()); ProcCall1_PI_PT.SetInputCtrlParamTuple("index", task.index);//参数1-9 ProcCall1_PI_PT.SetInputCtrlParamTuple("posX", task.posX); ProcCall1_PI_PT.SetInputCtrlParamTuple("posY", task.posY); ProcCall1_PI_PT.SetInputCtrlParamTuple("GerberPath",new HTuple( task.drawingPagePath));//美尚没有 //设置外部函数输入 if ((task.PTandLinePos != null) && (task.PTandLinePos[0] != 0)) { double[] posarray = new double[23]; posarray[0] = task.PTandLinePos[0]; posarray[1] = task.PTandLinePos[2]; posarray[2] = task.PTandLinePos[4]; posarray[3] = task.PTandLinePos[6]; posarray[4] = task.PTandLinePos[8]; for (int i = 0; i < 18; i++) { posarray[5 + i] = task.PTandLinePos[10 + i]; } ProcCall1_PI_PT.SetInputCtrlParamTuple("UserPose", posarray); ///// /// //string directory = Config.LogPath + "\\" + DateTime.Now.ToString("yyyyMM") + "\\"; //if (!System.IO.Directory.Exists(directory)) // System.IO.Directory.CreateDirectory(directory); //File.AppendAllText(directory + "sizeData.log", "data:" + string.Join(",", posarray) + "\r\n"); } else { double[] posarray = new double[23]; ProcCall1_PI_PT.SetInputCtrlParamTuple("UserPose", posarray); } } if (task.index == 777) { ProcCall1_PI_PT.SetInputIconicParamObject("ContoursAffineTrans1", task.ContoursAffineTrans1_Out); } else { HObject ContoursAffineTrans1; HOperatorSet.GenEmptyObj(out ContoursAffineTrans1); ProcCall1_PI_PT.SetInputIconicParamObject("ContoursAffineTrans1", ContoursAffineTrans1); } step = 3; ProcCall1_PI_PT.Execute();//执行外部函数 step = 4; //获取外部函数输出 switch (task.index) { case 777://比对结果 step = 10; task.CompResult = (double)ProcCall1_PI_PT.GetOutputCtrlParamTuple("RES") == 1;//结果,1为true,0为false step = 11; if (!task.CompResult) { var Defects_X = ProcCall1_PI_PT.GetOutputCtrlParamTuple("Defects_X"); var Defects_Y = ProcCall1_PI_PT.GetOutputCtrlParamTuple("Defects_Y"); var Defects_LeftTop_X = ProcCall1_PI_PT.GetOutputCtrlParamTuple("Defects_LeftTop_X"); var Defects_LeftTop_Y = ProcCall1_PI_PT.GetOutputCtrlParamTuple("Defects_LeftTop_Y"); var Defects_RightBottom_X = ProcCall1_PI_PT.GetOutputCtrlParamTuple("Defects_RightBottom_X"); var Defects_RightBottom_Y = ProcCall1_PI_PT.GetOutputCtrlParamTuple("Defects_RightBottom_Y"); var Contour_Image = ProcCall1_PI_PT.GetOutputIconicParamObject("Contour_Image"); //var Zoom_Image = ProcCall1_PI_PT.GetOutputIconicParamObject("Zoom_Image"); var Defects_Type = ProcCall1_PI_PT.GetOutputCtrlParamTuple("Defects_Type"); var Defects_Index = ProcCall1_PI_PT.GetOutputCtrlParamTuple("Defects_Index"); step = 12; //对比打标图:显示在UI上,以后修复台用 //task.Zoom_Image_mat = yolo5.DrawContour_Opencv(Contour_Image, Zoom_Image, Defects_LeftTop_X, Defects_LeftTop_Y, Defects_RightBottom_X, Defects_RightBottom_Y); //新YOLO.DLL task.defectInfor2RestorationDesk = new List>(); task.Zoom_Image_mat = yolo5.DrawContour_Opencv(Contour_Image, image, Defects_LeftTop_X, Defects_LeftTop_Y, Defects_RightBottom_X, Defects_RightBottom_Y, Defects_Type, Defects_Index, Defects_X, Defects_Y, out task.defectInfor2RestorationDesk); //WarningEvent?.Invoke(WarningEnum.Normal, $"SizeLib 777 call DrawContour_Opencv(),Defects_LeftTop_X={Defects_LeftTop_X}," + // $"Defects_LeftTop_Y={Defects_LeftTop_Y},Defects_RightBottom_X={Defects_RightBottom_X},Defects_RightBottom_Y={Defects_RightBottom_Y}," + // $"Defects_Type={Defects_Type},Defects_Index={Defects_Index},Defects_X={Defects_X},Defects_Y={Defects_Y}," + // $"defectInfor2RestorationDesk={JsonConvert.SerializeObject(task.defectInfor2RestorationDesk)}"); step = 13; task.Zoom_Image_mat = yolo5.ResizesMat_4(task.Zoom_Image_mat); //大图缺陷坐标转换到图纸坐标 step = 14; if (!string.IsNullOrWhiteSpace(task.drawingPagePath) && task.defectInfor2RestorationDesk != null && task.defectInfor2RestorationDesk.Count > 0) task.defectInfor2RestorationDeskPage = yolo5.DefectDrawGerberImage(task.drawingPagePath, task.defectInfor2RestorationDesk); } break; case 111: task.MarkPointList[0] = (double)ProcCall1_PI_PT.GetOutputCtrlParamTuple("PoseMarkX_1"); task.MarkPointList[1] = (double)ProcCall1_PI_PT.GetOutputCtrlParamTuple("PoseMarkY_1"); break; case 222: task.MarkPointList[2] = (double)ProcCall1_PI_PT.GetOutputCtrlParamTuple("PoseMarkX_2"); task.MarkPointList[3] = (double)ProcCall1_PI_PT.GetOutputCtrlParamTuple("PoseMarkY_2"); break; case 333: task.MarkPointList[4] = (double)ProcCall1_PI_PT.GetOutputCtrlParamTuple("PoseMarkX_3"); task.MarkPointList[5] = (double)ProcCall1_PI_PT.GetOutputCtrlParamTuple("PoseMarkY_3");//ContoursAffineTrans1 task.ContoursAffineTrans1_Out = ProcCall1_PI_PT.GetOutputIconicParamObject("ContoursAffineTrans1_Out"); break; case 444: task.MarkPointList[6] = (double)ProcCall1_PI_PT.GetOutputCtrlParamTuple("PoseMarkX_4"); task.MarkPointList[7] = (double)ProcCall1_PI_PT.GetOutputCtrlParamTuple("PoseMarkY_4"); break; case 3333: //Tag使用,同时继续获取使用default时时校正和其它值 step = 80; if (!string.IsNullOrWhiteSpace( task.sizeTag)) task.posePT= ProcCall1_PI_PT.GetOutputCtrlParamTuple("posePT").DArr; goto default; default: step = 90; task.PT1 = (double)ProcCall1_PI_PT.GetOutputCtrlParamTuple("DistancePT1");//index=8 PT1=PT2 task.PT2 = ProcCall1_PI_PT.GetOutputCtrlParamTuple("DistancePT2"); task.Shanxian = (double)ProcCall1_PI_PT.GetOutputCtrlParamTuple("Distance3Median"); //task.RowP = (double)ProcCall1_PI_PT.GetOutputCtrlParamTuple("RowP"); task.Circle_Ymm = (double)ProcCall1_PI_PT.GetOutputCtrlParamTuple("Circle_Ymm"); task.Circle_Xmm = (double)ProcCall1_PI_PT.GetOutputCtrlParamTuple("Circle_Xmm"); task.offsetX = (double)ProcCall1_PI_PT.GetOutputCtrlParamTuple("offsetX"); task.offsetY = (double)ProcCall1_PI_PT.GetOutputCtrlParamTuple("offsetY"); break; } step = 100; ProcCall1_PI_PT.Dispose(); Program1.Dispose(); step = 101; task.isSucceed = true; task.resultInfo = "成功"; callback(task); step = 102; } Thread.Sleep(5); } catch (Exception ex) { WarningEvent?.Invoke(WarningEnum.Low, $"SizeLib task err({step}) index({task.index}):"+ 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 processName;//只为回调记录当前工序信息 public string engineName,sizeTag; /// /// 源文件 /// public string file_path; public double posX,posY; public Bitmap bmp; public string drawingPagePath = "";//.gbx图纸路径 //2023-10-27 新增图纸选择pt点位与线宽点位 public double[] PTandLinePos; /// /// 比对(index=777); 计算Mark(111/222/333/444); 尺寸(1-9); 轴偏移调整(10,20,30...) /// public int index; //index=8 PT1=PT2 /// /// 完成后回调 /// public Action finishEvent; public long createTime = DateTime.Now.Ticks; //==结果返回 /// /// 比对结果(index=777) /// public bool CompResult; public Mat Zoom_Image_mat;//对比打标图:777比对失败时计算得出,后面显示到UI 以后修复台用 public List> defectInfor2RestorationDesk, defectInfor2RestorationDeskPage;//对比未通过坐标信息,合并到缺陷检测中的 //打标缺陷转为图纸的坐标; //MARK点 public double[] MarkPointList = { 0, 0, 0, 0, 0, 0, 0, 0 }; public HObject ContoursAffineTrans1_Out;//index=333时输出,供后面多个777比对时输入使用 public double[] posePT;//index=3333 && !isEmpty(sizeTag) 才取此数组值,len为0时急停 // 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; 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; } } } }