|
- using HalconDotNet;
- using MaiMuAOI.SysCtrl;
- using MaiMuControl.Device;
- using MaiMuControl.Device.CamDev;
- 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 MaiMuAOI.ImageProcessing
- {
- public class SizeLib : IDisposable
- {
- public Action<WarningEnum, string> WarningEvent;
- /// <summary>
- /// 检测结果JSON(原图,结果)
- /// </summary>
- public Action<SizeTask> finishEvent;
- /// <summary>
- /// 是否打开设备成功
- /// </summary>
- 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.Himage != null)
- image = task.Himage.Clone();
- //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("Adapter", task.Adapter);
-
- if(task.AdapterPos != null)
- ProcCall1_PI_PT.SetInputCtrlParamTuple("UserPose", task.AdapterPos);
- else
- 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 if (task.AdapterPos != null)
- {
- ProcCall1_PI_PT.SetInputCtrlParamTuple("Adapter", task.Adapter);
- ProcCall1_PI_PT.SetInputCtrlParamTuple("UserPose", task.AdapterPos);
- }
- else
- {
- double[] posarray = new double[23];
- task.Adapter = new int[9] { 5, 18 ,0,0,0,0,0,0,0};
- ProcCall1_PI_PT.SetInputCtrlParamTuple("Adapter", task.Adapter);
- 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<List<string>>();
- 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);
-
- if (ConfMgr.Instance.SysConfigParams.OpenFlawDistribution)
- {
- //大图缺陷坐标转换到图纸坐标
- 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 = 5;
- //尺寸标注
- if (task.index != 3333)
- {
- try
- {
- step = 6;
- var posePT = ProcCall1_PI_PT.GetOutputCtrlParamTuple("posePT").DArr;
- step = 7;
- //Yolo_Class yolo = new Yolo_Class();
- step = 8;
- var mat = CamDev.HImageToMat(image);
- step = 9;
- //task.SaveMat = yolo.DisplayLines(mat, posePT, task.index).Clone();
- task.SaveMat = yolo5.DisplayLines(mat, posePT, task.index);
- }
- catch (Exception ex)
- {
- //WarningEvent?.Invoke(WarningEnum.Low, $"SizeLib task err({step}) index({task.index}):" + ex.Message);
- task.SaveMat = null;
- }
- }
-
-
- 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<SizeTask> taskList = new List<SizeTask>();
- public class SizeTask
- {
- public int stepIndex;//只为回调记录当前工序信息
- public string processName;//只为回调记录当前工序信息
-
- public string engineName,sizeTag;
- /// <summary>
- /// 源文件
- /// </summary>
- public string file_path;
- public double posX,posY;
- public HObject Himage;
- public string drawingPagePath = "";//.gbx图纸路径
-
- //2023-10-27 新增图纸选择pt点位与线宽点位
- public int[] Adapter;
- public double[] PTandLinePos;
- public double[] AdapterPos;
- /// <summary>
- /// 比对(index=777); 计算Mark(111/222/333/444); 尺寸(1-9); 轴偏移调整(10,20,30...)
- /// </summary>
- public int index; //index=8 PT1=PT2
- /// <summary>
- /// 完成后回调
- /// </summary>
- public Action<SizeTask> finishEvent;
- public long createTime = DateTime.Now.Ticks;
-
- //==结果返回
- /// <summary>
- /// 比对结果(index=777)
- /// </summary>
- public bool CompResult;
- public Mat Zoom_Image_mat;//对比打标图:777比对失败时计算得出,后面显示到UI 以后修复台用
- public List<List<string>> 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 Mat SaveMat;
- }
-
- 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();
- }
- /// <summary>
- /// Bitmap转HObject灰度图
- /// </summary>
- /// <param name="bmp">Bitmap图像</param>
- /// <param name="image">HObject图像</param>
- 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;
- }
- }
- }
- }
|