|
- //#define Online_One
-
- using CCWin.Win32.Const;
- using DocumentFormat.OpenXml.Office2010.ExcelAc;
- using GeBoShi.SysCtrl;
- using HZH_Controls.Controls;
- using MaiMuControl.Device;
- using Models;
- using OpenCvSharp;
- using S7.Net.Types;
- using System;
- using System.Collections.Generic;
- using System.Data;
- using System.Diagnostics;
- using System.Linq;
- using System.Reflection;
- using System.Runtime.InteropServices;
- using System.Text;
- using System.Threading;
- using System.Threading.Tasks;
- using static System.ComponentModel.Design.ObjectSelectorEditor;
-
- namespace GeBoShi.ImageDefect
- {
- public class DefectLib
- {
- #region C++dll
- private const string dll_path = "yolo_trt.dll";
- [DllImport(dll_path, CharSet = CharSet.Unicode, CallingConvention = CallingConvention.StdCall)]
- static extern IntPtr CreateDetector(string model_path);
-
- [DllImport(dll_path, CharSet = CharSet.Unicode, CallingConvention = CallingConvention.Cdecl)]
- extern static bool DestroyDetector(IntPtr detector);
-
- /// <summary>
- /// 非0值表示成功,0表示失败 返回小图张数
- /// </summary>
- /// <param name="detector"></param>
- /// <returns></returns>
- [DllImport(dll_path, CharSet = CharSet.Unicode, CallingConvention = CallingConvention.StdCall)]
- static extern int GetBatchSize(IntPtr detector);
-
- [DllImport(dll_path, CharSet = CharSet.Unicode, CallingConvention = CallingConvention.StdCall)]
- static extern bool Detect(IntPtr detector, ref byte bgrs_data,
- int image_num, int width, int height, int channels,
- float conf_threshold, float iou_threshold,
- ref float output, int output_size, ref int object_num,
- int expand_pixel);
- #endregion
-
- public Action<WarningEnum, string> WarningEvent;
- /// <summary>
- /// 检测结果JSON(原图,结果)
- /// </summary>
- public Action<DefectTask> finishEvent;
- /// <summary>
- /// 是否打开设备成功
- /// </summary>
- public bool IsInit { get; private set; } = false;
-
- private IntPtr detector = IntPtr.Zero;
-
- private Thread t_task, t_task_operation, t_task_maketag, t_task_defectover;
- //=======task list
- private List<DefectTask> taskList = new List<DefectTask>();
- private List<DefectTask> taskOperationList = new List<DefectTask>();
- private List<DefectTask> taskMakeTagList = new List<DefectTask>();
- private List<DefectTask> taskDefectOverList = new List<DefectTask>();
-
- private string preModelName = "";
-
- #region 图片处理参数
- private readonly int image_width = 2048;
- private readonly int image_hight = 2048;
- private readonly int image_channels = 3;
- private readonly int image_bytes = 2048 * 2048 * 3;
- private readonly int detect_elem_size = 7; //维度数据结果,x y w h conf classid
- private readonly int detect_max_object_num = 20;//这个指的是一张子图可能最多给你返回的目标个球
-
- public Action<int, int> QueueCountEvent;//0/1/2, 数量
- #endregion
- public DefectLib()
- {
- }
-
- public bool start()
- {
- try
- {
- //detector = CreateDetector(Config.model_path, Config.labels_path, true, 6);
- //if (detector == IntPtr.Zero)
- // throw new Exception("模型初始化失败!");
- preModelName = "";
-
- IsInit = true;
- taskList.Clear();
- taskOperationList.Clear();
- taskMakeTagList.Clear();
-
- #if Online_One
- t_task = new System.Threading.Thread(run);
- t_task.IsBackground = true;
- t_task.Start();
- #else
- t_task = new System.Threading.Thread(runStep);
- t_task.IsBackground = true;
- t_task.Start();
-
- t_task_operation = new System.Threading.Thread(run2);
- t_task_operation.IsBackground = true;
- t_task_operation.Start();
-
- t_task_maketag = new System.Threading.Thread(run3);
- t_task_maketag.IsBackground = true;
- t_task_maketag.Start();
-
- //t_task_defectover = new System.Threading.Thread(run4);
- //t_task_defectover.IsBackground = true;
- //t_task_defectover.Start();
- #endif
- 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;
- preModelName = "";
- //释放模型
- if (detector != IntPtr.Zero)
- {
- DestroyDetector(detector);
- detector = IntPtr.Zero;
- }
- if (t_task != null)
- {
- bool b = t_task.Join(5000);
- if (!b) t_task.Abort();
- t_task = null;
- }
-
- if (t_task_operation != null)
- {
- bool b = t_task_operation.Join(5000);
- if (!b) t_task_operation.Abort();
- t_task_operation = null;
- }
-
- if (t_task_maketag != null)
- {
- bool b = t_task_maketag.Join(5000);
- if (!b) t_task_maketag.Abort();
- t_task_maketag = null;
- }
-
- //if (t_task_defectover != null)
- //{
- // bool b = t_task_defectover.Join(5000);
- // if (!b) t_task_defectover.Abort();
- // t_task_defectover = null;
- //}
- taskList.Clear();
- taskOperationList.Clear();
- taskMakeTagList.Clear();
- taskDefectOverList.Clear();
- }
- catch { }
- }
-
- /// <summary>
- /// 切割(先左右,后上下)
- /// </summary>
- /// <param name="mat"></param>
- /// <param name="width"></param>
- /// <param name="height"></param>
- /// <returns></returns>
- private Mat[] OpenCVToCutsMat(Mat mat, int width, int height)
- {
- Mat[] array = new Mat[mat.Width / width * mat.Height / height];
- int num = 0;
- for (int i = 0; i < mat.Height / height; i++)
- {
- for (int j = 0; j < mat.Width / width; j++)
- {
- int x = j * width;
- int y = i * height;
- System.Drawing.Rectangle rectangle = new System.Drawing.Rectangle(x, y, width, height);
- Rect roi = new Rect(rectangle.X, rectangle.Y, rectangle.Width, rectangle.Height);
- array[num] = new Mat(mat, roi).Clone();
- num++;
- }
- }
-
- return array;
- }
-
- public static string ToGB2312(int codepage, string str)
- {
- try
- {
- Encoding cp850 = Encoding.GetEncoding(codepage);
- Encoding gb2312 = Encoding.GetEncoding("gb2312");//Encoding.Default ,936
- byte[] temp = cp850.GetBytes(str);
- return Encoding.GetEncoding("gb2312").GetString(temp, 0, temp.Length);
- }
- catch (Exception ex)//(UnsupportedEncodingException ex)
- {
- Console.Write(ex.Message);
- return null;
- }
- }
-
- private void runStep()
- {
- int step = 0;
- while (IsInit)
- {
- if (taskList.Count < 1)
- {
- Thread.Sleep(25);
- continue;
- }
-
- //
- step = 1;
- var task = pop();
- try
- {
- if (task != null)
- {
- Stopwatch stopwatch = Stopwatch.StartNew();
- step = 2;
- if (preModelName != task.modelName)
- {
- step = 3;
- //先释放模型
- if (detector != IntPtr.Zero)
- {
- step = 4;
- DestroyDetector(detector);
- detector = IntPtr.Zero;
- }
- step = 5;
- string modelPath = $"{ConfMgr.Instance.SysConfigParams.AIModelPath}\\{task.modelName}";
-
- detector = CreateDetector(modelPath);
- if (detector == IntPtr.Zero)
- throw new Exception($"模型({modelPath})初始化失败!");
- step = 6;
- preModelName = task.modelName;
- }
- //源图
- //Bitmap bmp = yolo1.Read2Bmp(file_path);
- //切割图像,输入图像格式14208*10640
- stopwatch.Start();
- //task.resizeBmp = OpenCVUtil.resize( task.bmp.Clone(), task.resize.Width, task.resize.Height);//在外面已做了resize
-
- //Cv2.CvtColor(task.bmp, task.bmpBgr2rgb, ColorConversionCodes.BGR2RGB);
- //task.bmps_cut = OpenCVToCutsMat(task.bmpBgr2rgb, image_width, image_hight); //这里cut时之前加的clone
- step = 7;
- task.bmps_cut = OpenCVToCutsMat(task.bmp, image_width, image_hight); //这里cut时之前加的clone
- stopwatch.Stop();
- task.stopwatch[0] = stopwatch.ElapsedMilliseconds;
-
- //Resize图像
- //stopwatch.Restart();
- //task.bmps_resize = yolo1.OpenCVToResizesMat(task.bmps_cut, task.resize.Width, task.resize.Height);
- //stopwatch.Stop();
- //task.stopwatch[1] = stopwatch.ElapsedMilliseconds;
-
- //预处理模型
- //stopwatch.Restart();
- //task.tensors = yolo1.PreprocessImageMat(task.bmps_resize);
- //stopwatch.Stop();
- //task.stopwatch[2] = stopwatch.ElapsedMilliseconds;
- step = 8;
- lock (taskOperationList)
- {
- taskOperationList.Add(task);
- QueueCountEvent?.BeginInvoke(1, taskOperationList.Count, null, null);
- }
- step = 9;
- }
- }
- catch (Exception ex)
- {
- WarningEvent?.Invoke(WarningEnum.Low, $"DefectLib task1 err({step}):" + ex.Message);
- task.isSucceed = false;
- task.resultInfo = ex.Message;
- callback(task);
- }
- Thread.Sleep(5);
- }
- }
- //推理
- private void run2()
- {
- QualifiedLimit qualifiedLimit;
- while (IsInit)
- {
- if (taskOperationList.Count < 1)
- {
- Thread.Sleep(25);
- continue;
- }
-
- //
- var task = pop2();
- int cut_count = 0, step = 0;
- try
- {
- if (task != null && task.bmps_cut.Count() > 0)
- {
- //WarningEvent?.Invoke(DateTime.Now,WarningEnum.Low, "DefectLib tasks 运行推理...");
- cut_count = task.bmps_cut.Count();
- Stopwatch stopwatch = Stopwatch.StartNew();
- //====推理(必需单队列)
- stopwatch.Start();
- // 把数据转为byte数组,【h, w, c】的bgr格式,第一张在前,第二张在后
- byte[] imgData = new byte[image_bytes * cut_count];
- for (int i = 0; i < cut_count; i++)
- Marshal.Copy(task.bmps_cut[i].Data, imgData, image_bytes * i, image_bytes);
- step = 1;
- stopwatch.Stop();
- task.stopwatch[1] = stopwatch.ElapsedMilliseconds;
- stopwatch.Restart();
-
- task.output = new float[cut_count * detect_elem_size * detect_max_object_num];
- task.output_num = new int[cut_count];
- //执行推理
- step = 2;
- bool ok = Detect(detector, ref imgData[0], cut_count, image_width, image_hight, image_channels,
- 0.25f, 0.45f, ref task.output[0], task.output.Length, ref task.output_num[0], task.expand_pixel);
- //bool ok = Detect(_detector, ref imgData[0], imgs.Count, ImageWidth, image_hight, image_channels,
- // 0.25f, 0.45f, ref output[0], output.Length, ref output_num[0]);
- step = 3;
- stopwatch.Stop();
- task.stopwatch[2] = stopwatch.ElapsedMilliseconds;
- //WarningEvent?.Invoke(DateTime.Now,WarningEnum.Low, $"DefectLib tasks 结果推理={ok}");
- for (int i = 0; i < cut_count; i++)
- task.bmps_cut[i].Dispose();
- if (ok == false)
- throw new Exception($"推理失败或者输入数组太小({cut_count})");
-
- //
- lock (taskMakeTagList)
- {
- taskMakeTagList.Add(task);
- QueueCountEvent?.BeginInvoke(2, taskMakeTagList.Count, null, null);
- }
- }
- }
- catch (Exception ex)
- {
- WarningEvent?.Invoke(WarningEnum.Low, $"DefectLib task2 err({step}):({cut_count}){ex.Message}");
- task.isSucceed = false;
- task.resultInfo = ex.Message;
- callback(task);
- }
- Thread.Sleep(5);
- }
- }
- //打标
- private void run3()
- {
- QualifiedLimit qualifiedLimit;
- while (IsInit)
- {
- if (taskMakeTagList.Count < 1)
- {
- Thread.Sleep(25);
- continue;
- }
-
- //
- var task = pop3();
- int liStep = 0;
- try
- {
- Stopwatch stopwatch = Stopwatch.StartNew();
- stopwatch.Restart();
- int cut_count = task.bmps_cut.Count();//上面bmps_cut已销毁
- int colNum = task.bmp.Width / image_width;
- int rowNum = task.bmp.Height / image_hight;
- int count = 0;
- liStep = 3;
-
- //车用革去除接头处横档误判
- bool haveJieTou = false;
- List<DefectLabelInfo> DefectLabelInfoList = new List<DefectLabelInfo>();
-
- for (int i = 0; i < cut_count; i++)
- {
- liStep = i * 100;
- task.resultInfo += $"第 {i}/{cut_count} 张小图(大图索引{task.photoIndex}): 缺陷数 = {task.output_num[i]}-{task.output.Length}\n";
- //task.resultInfo +=$"大图({task.tag})[{task.bmp.Width}*{task.bmp.Height}],第 {i + 1}/{cut_count} 张小图[{task.bmps_cut[i].Width}*{task.bmps_cut[i].Height}]: 瑕疵output_num = {output_num[i]}\n";
- #region 检测信息汇总
- for (int j = 0; j < task.output_num[i]; j++)//缺陷数
- {
- liStep += j + 10000;//0
- //WarningEvent?.Invoke(DateTime.Now,WarningEnum.Low, $"-------");
- int index = count * detect_elem_size;
-
- // 打印输出信息(示例代码,根据实际情况进行修改和格式化)
- // 获取输出信息
- int x = (int)task.output[index];
- int y = (int)task.output[index + 1];
- int w = (int)task.output[index + 2];
- int h = (int)task.output[index + 3];
- int classId = (int)task.output[index + 4];
- double confidence = Math.Round(task.output[index + 5], 2); //置信度
- double contrast = Math.Round(task.output[index + 6], 3);//对比度
- //y = image_hight-y-h;//转到右下角为原点
- count++;
-
- liStep+= 10000;//0
- //var cmW = Math.Round(w * task.widthRatio / task.cm2px_x, 2);
- //var cmH = Math.Round(h * task.widthRatio / task.cm2px_y, 2);
- // 打印输出信息
- //task.resultInfo += $"----{i}----col:{i % colNum}/{colNum} row:{i / colNum}/{colNum}-----------\n目标:{j + 1} 类别ID:{classId} 置信度:{confidence} 对比度:{contrast} 坐标:({x},{y})-({x + w},{y + h}) 宽高:w={w},h={h}; \n";
-
- DefectLabelInfoList.Add(new DefectLabelInfo()
- {
- x = (int)task.output[index],
- y = (int)task.output[index + 1],
- w = (int)task.output[index + 2],
- h = (int)task.output[index + 3],
- classId = (int)task.output[index + 4],
- confidence = Math.Round(task.output[index + 5], 2), //置信度
- contrast = Math.Round(task.output[index + 6], 3),//对比度
- cmW = Math.Round(w * task.widthRatio / task.cm2px_x, 2),
- cmH = Math.Round(h * task.widthRatio / task.cm2px_y, 2),
- i = i,
- j = j,
- });
- }
-
- #endregion
- }
- liStep = 7777;
- #region 合并接头横档
- if (DefectLabelInfoList.Count > 0)
- DefectLabelInfoList = HeBingDefect(task.bmp.Width, "jietou", DefectLabelInfoList);
- if (DefectLabelInfoList.Count > 0)
- DefectLabelInfoList = HeBingDefect(task.bmp.Width, "hengdang", DefectLabelInfoList);
- if (DefectLabelInfoList.Count > 0)
- DefectLabelInfoList = HeBingDefect(task.bmp.Width, "jt", DefectLabelInfoList);
- if (DefectLabelInfoList.Count > 0)
- DefectLabelInfoList = HeBingDefect(task.bmp.Width, "hd", DefectLabelInfoList);
- if (DefectLabelInfoList.Count > 0)
- DefectLabelInfoList = HeBingDefect(task.bmp.Width, "bj", DefectLabelInfoList);
- if (DefectLabelInfoList.Count > 0)
- DefectLabelInfoList = HeBingDefect(task.bmp.Width, "zj", DefectLabelInfoList);
- #endregion
- //结果过滤
- #region 结果过滤
-
- liStep = 8888;
- if (DefectLabelInfoList.Count > 0)
- {
- //降序排序,先得到是否有接头检出
- List<DefectLabelInfo> DefectLabelInfoListByClassID = DefectLabelInfoList.OrderByDescending(t => t.classId).ToList();//降序
- for (int q = 0; q < DefectLabelInfoList.Count; q++)
- {
- //是否满足此产品标准
- if (task.qualifiedLimitList != null && task.qualifiedLimitList.Count > 0)
- {
- qualifiedLimit = task.qualifiedLimitList.FirstOrDefault(m => m.Code == task.labelDic[DefectLabelInfoList[q].classId]);
- if (qualifiedLimit != null)
- {
- //if ((qualifiedLimit.ZXD > 0 && qualifiedLimit.ZXD > confidence)
- // || (qualifiedLimit.ContrastTop + qualifiedLimit.ContrastLower > 0 && x> qualifiedLimit.ContrastLower && x < qualifiedLimit.ContrastTop)
- // || (qualifiedLimit.Area > 0 && qualifiedLimit.Area > cmW * cmH))
- if (DefectLabelInfoList[q].confidence <= qualifiedLimit.ZXD)//confidence > qualifiedLimit.ZXD 是瑕疵 才继续判断下面的两个条件
- {
- task.resultInfo += $" 置信度不满足此产品瑕疵标准,跳过! \n";
- continue;
- }
-
- //下限<对比度<上限:不是瑕疵
- var ContrastTotal = qualifiedLimit.ContrastTop + qualifiedLimit.ContrastLower;
- if (qualifiedLimit.IsOR)
- {
- if (!(
- (qualifiedLimit.Area <= 0 || DefectLabelInfoList[q].cmW * DefectLabelInfoList[q].cmH >= (qualifiedLimit.Area / 100)) ||
- (ContrastTotal <= 0 || (DefectLabelInfoList[q].contrast < qualifiedLimit.ContrastLower || DefectLabelInfoList[q].contrast > qualifiedLimit.ContrastTop))))
- {
- task.resultInfo += $" 不满足此产品瑕疵标准,跳过! \n";
- //WarningEvent?.Invoke(DateTime.Now,WarningEnum.Low, $"判断不是瑕疵:类别ID:{classId}; 置信度({confidence},[{qualifiedLimit.ZXD}]); isOr({qualifiedLimit.IsOR}); 面积({cmW * cmH},[{ qualifiedLimit.Area}]); 对比度({contrast},[{qualifiedLimit.ContrastLower}-{qualifiedLimit.ContrastTop}])");
- continue;
- }
- }
- else
- {
- if (!(
- (qualifiedLimit.Area <= 0 || DefectLabelInfoList[q].cmW * DefectLabelInfoList[q].cmH >= (qualifiedLimit.Area / 100)) &&
- (ContrastTotal <= 0 || (DefectLabelInfoList[q].contrast < qualifiedLimit.ContrastLower || DefectLabelInfoList[q].contrast > qualifiedLimit.ContrastTop))))
- {
- task.resultInfo += $" 不满足此产品瑕疵标准,跳过! \n";
- //WarningEvent?.Invoke(DateTime.Now,WarningEnum.Low, $"判断不是瑕疵:类别ID:{classId}; 置信度({confidence},[{qualifiedLimit.ZXD}]); isOr({qualifiedLimit.IsOR}); 面积({cmW * cmH},[{ qualifiedLimit.Area}]); 对比度({contrast},[{qualifiedLimit.ContrastLower}-{qualifiedLimit.ContrastTop}])");
- continue;
- }
- }
- if (task.labelDic[DefectLabelInfoList[q].classId] == "jietou")
- haveJieTou = true;
- if (haveJieTou && (task.labelDic[DefectLabelInfoList[q].classId] == "hengdang"))
- {
- task.resultInfo += $" 判断为接头处横档,跳过! \n";
- continue;
- }
- //WarningEvent?.Invoke(DateTime.Now,WarningEnum.Low, $"判断是瑕疵:类别ID:{classId}; 置信度({confidence},[{qualifiedLimit.ZXD}]); isOr({qualifiedLimit.IsOR}); 面积({cmW * cmH},[{ qualifiedLimit.Area}]); 对比度({contrast},[{qualifiedLimit.ContrastLower}-{qualifiedLimit.ContrastTop}])");
- }
- }
- liStep++;
- //1
- int penLine = 20;
- //打标
- var point1 = new OpenCvSharp.Point((DefectLabelInfoList[q].i % colNum) * image_width + DefectLabelInfoList[q].x - penLine/2, (DefectLabelInfoList[q].i / colNum) * image_hight + DefectLabelInfoList[q].y - penLine / 2);
- var point2 = new OpenCvSharp.Point(point1.X + DefectLabelInfoList[q].w + penLine / 2, point1.Y + DefectLabelInfoList[q].h + penLine / 2);
- liStep++;//2
- task.resultInfo += $" 转换到大图坐标(px):p1={point1.X},{point1.Y}; p2={point2.X},{point2.Y}\n";
-
-
-
- Cv2.Rectangle(task.bmpTag, point1, point2, new Scalar(0.0, 0.0, 255.0), penLine);//画打标点
-
- //WarningEvent?.Invoke(DateTime.Now,WarningEnum.Low, $"保存第 {count} 行缺陷信息;");
- int px = (point1.X - task.xw) > 0 ? (point1.X - task.xw) : 0;
- var cmX = Math.Round(px * task.widthRatio / task.cm2px_x, 2);
- var cmY = Math.Round((task.bmp.Height - point1.Y - DefectLabelInfoList[q].h) * task.widthRatio / task.cm2px_y, 2);//外面计Y从右下角为原点
- liStep++;//3
- task.resultInfo += $" 转换到大图坐标(cm)[widthRatio={task.widthRatio}]:x={cmX},y={cmY}; w={DefectLabelInfoList[q].cmW},h={DefectLabelInfoList[q].cmH}\n";
- task.excelTable.Rows.Add($"{task.photoIndex}", cmX, cmY, DefectLabelInfoList[q].cmW, DefectLabelInfoList[q].cmH, DefectLabelInfoList[q].j + 1, DefectLabelInfoList[q].classId, DefectLabelInfoList[q].confidence, Utils.ContrastToPercent(DefectLabelInfoList[q].contrast));
-
- liStep++;//4
- //切缺陷小图
- //WarningEvent?.Invoke(DateTime.Now,WarningEnum.Low, $"保存第 {count} 个缺陷小图;");
- int left, top, decX, decY;
- //decX = (DefectLabelInfoList[q].w > 236 ? 20 : 256 - DefectLabelInfoList[q].w) / 2;
- //decY = (DefectLabelInfoList[q].h > 236 ? 20 : 256 - DefectLabelInfoList[q].h) / 2;
- int tdecX = (DefectLabelInfoList[q].w /2 ) / 2;
- int tdecY = DefectLabelInfoList[q].w/ DefectLabelInfoList[q].h > 4 ? DefectLabelInfoList[q].w /8 : (DefectLabelInfoList[q].h /1 ) / 2;
-
- decX = (DefectLabelInfoList[q].w > 236 ? tdecX : 256 - DefectLabelInfoList[q].w) / 2;
- decY = (DefectLabelInfoList[q].h > 236 ? tdecY : 256 - DefectLabelInfoList[q].h) / 2;
-
- left = point1.X - decX;
- top = point1.Y - decY;
- if (left < 0) left = 0;
- if (top < 0) top = 0;
-
- int width = DefectLabelInfoList[q].w + decX * 2;
- int height = DefectLabelInfoList[q].h + decY * 2;
- if (left + width > task.bmp.Width - 1) width = task.bmp.Width - left - 1;
- if (top + height > task.bmp.Height - 1) height = task.bmp.Height - top - 1;
- liStep++;//5
- Rect roi = new Rect(left, top, width, height);
- liStep++;//6
- if (height < 1 || width < 1)
- {
- task.resultInfo += $" 打标到大图坐标Rect(px):left={left},top={top}; width={width},height={height}\n";
- task.resultInfo += $" test point1.Y={point1.Y},h={DefectLabelInfoList[q].h}; top={top},mat.Height={task.bmp.Height}\n================\n";
- WarningEvent?.Invoke(WarningEnum.Normal, task.resultInfo);
- }
-
- //保存
- //string filename = $"{Config.appBasePath}\\temp\\{task.tag}\\{task.tag}_X{mmX.ToString()}_Y{mmY.ToString()}_W{mmW.ToString()}_H{mmH.ToString()}_目标{j + 1}_类别{classId}_置信度{confidence}.bmp";
- //OpenCvSharp.Extensions.BitmapConverter.ToBitmap(new Mat(task.bmp, roi)).Save(filename, ImageFormat.Jpeg);
-
- task.lstDefectBmp.Add(new Mat(task.bmpTag, roi).Clone());
- liStep++;//7
- }
- }
- #endregion
- liStep = 99;
- stopwatch.Stop();
- task.stopwatch[3] = stopwatch.ElapsedMilliseconds;
-
- task.isSucceed = true;
-
- //lock (taskDefectOverList)
- //{
- // taskDefectOverList.Add(task);
- // QueueCountEvent?.BeginInvoke(3, taskDefectOverList.Count, null, null);
- //}
-
- callback(task);
- Thread.Sleep(5);
- }
- catch (Exception ex)
- {
- WarningEvent?.Invoke(WarningEnum.Low, $"DefectLib task3 err({liStep}):" + ex.Message + $"-{task.resultInfo}");
- task.isSucceed = false;
- task.resultInfo = ex.Message;
- callback(task);
- }
- }
- }
- //最终处理
- private void run()
- {
- int step = 0;
- QualifiedLimit qualifiedLimit;
- while (IsInit)
- {
- if (taskList.Count < 1)
- {
- Thread.Sleep(5);
- continue;
- }
- step = 1;
- var task = pop();
- try
- {
- if (task != null)
- {
- Stopwatch stopwatch = Stopwatch.StartNew();
- step = 2;
- if (preModelName != task.modelName)
- {
- step = 3;
- //先释放模型
- if (detector != IntPtr.Zero)
- {
- step = 4;
- DestroyDetector(detector);
- detector = IntPtr.Zero;
- }
- step = 5;
- string modelPath = $"{ConfMgr.Instance.SysConfigParams.AIModelPath}\\{task.modelName}";
-
- detector = CreateDetector(modelPath);
- if (detector == IntPtr.Zero)
- throw new Exception($"模型({modelPath})初始化失败!");
- step = 6;
- preModelName = task.modelName;
- }
- //源图
- stopwatch.Start();
- step = 7;
- //裁切
- task.bmps_cut = OpenCVToCutsMat(task.bmp, image_width, image_hight); //这里cut时之前加的clone
- stopwatch.Stop();
- task.stopwatch[0] = stopwatch.ElapsedMilliseconds;
- step = 8;
- int cut_count = task.bmps_cut.Count();
- //====推理(必需单队列)
- stopwatch.Restart();
- // 把数据转为byte数组,【h, w, c】的bgr格式,第一张在前,第二张在后
- byte[] imgData = new byte[image_bytes * cut_count];
- for (int i = 0; i < cut_count; i++)
- Marshal.Copy(task.bmps_cut[i].Data, imgData, image_bytes * i, image_bytes);
- step = 9;
- stopwatch.Stop();
- task.stopwatch[1] = stopwatch.ElapsedMilliseconds;
- stopwatch.Restart();
-
- task.output = new float[cut_count * detect_elem_size * detect_max_object_num];
- task.output_num = new int[cut_count];
- //执行推理
- step = 10;
- bool ok = Detect(detector, ref imgData[0], cut_count, image_width, image_hight, image_channels,
- 0.25f, 0.45f, ref task.output[0], task.output.Length, ref task.output_num[0], task.expand_pixel);
- step = 11;
- stopwatch.Stop();
- task.stopwatch[2] = stopwatch.ElapsedMilliseconds;
- stopwatch.Restart();
- //WarningEvent?.Invoke(DateTime.Now,WarningEnum.Low, $"DefectLib tasks 结果推理={ok}");
- for (int i = 0; i < cut_count; i++)
- task.bmps_cut[i].Dispose();
- if (ok == false)
- throw new Exception($"推理失败或者输入数组太小({cut_count})");
- step = 12;
- //打标
- cut_count = task.bmps_cut.Count();//上面bmps_cut已销毁
- int colNum = task.bmp.Width / image_width;
- int rowNum = task.bmp.Height / image_hight;
- int count = 0;
- step = 13;
-
- //车用革去除接头处横档误判
- bool haveJieTou = false;
- List<DefectLabelInfo> DefectLabelInfoList = new List<DefectLabelInfo>();
-
- for (int i = 0; i < cut_count; i++)
- {
- step = i * 100;
- task.resultInfo += $"第 {i}/{cut_count} 张小图(大图索引{task.photoIndex}): 缺陷数 = {task.output_num[i]}-{task.output.Length}\n";
- //task.resultInfo +=$"大图({task.tag})[{task.bmp.Width}*{task.bmp.Height}],第 {i + 1}/{cut_count} 张小图[{task.bmps_cut[i].Width}*{task.bmps_cut[i].Height}]: 瑕疵output_num = {output_num[i]}\n";
- #region 检测信息汇总
- for (int j = 0; j < task.output_num[i]; j++)//缺陷数
- {
- step += j + 10000;//0
- //WarningEvent?.Invoke(DateTime.Now,WarningEnum.Low, $"-------");
- int index = count * detect_elem_size;
-
- // 打印输出信息(示例代码,根据实际情况进行修改和格式化)
- // 获取输出信息
- int x = (int)task.output[index];
- int y = (int)task.output[index + 1];
- int w = (int)task.output[index + 2];
- int h = (int)task.output[index + 3];
- int classId = (int)task.output[index + 4];
- double confidence = Math.Round(task.output[index + 5], 2); //置信度
- double contrast = Math.Round(task.output[index + 6], 3);//对比度
- //y = image_hight-y-h;//转到右下角为原点
- count++;
-
- step += 10000;//0
-
- DefectLabelInfoList.Add(new DefectLabelInfo()
- {
- x = (int)task.output[index],
- y = (int)task.output[index + 1],
- w = (int)task.output[index + 2],
- h = (int)task.output[index + 3],
- classId = (int)task.output[index + 4],
- confidence = Math.Round(task.output[index + 5], 2), //置信度
- contrast = Math.Round(task.output[index + 6], 3),//对比度
- cmW = Math.Round(w * task.widthRatio / task.cm2px_x, 2),
- cmH = Math.Round(h * task.widthRatio / task.cm2px_y, 2),
- i = i,
- j = j,
- });
- }
-
- #endregion
- }
- step = 7777;
- #region 合并接头横档
- if (DefectLabelInfoList.Count > 0)
- DefectLabelInfoList = HeBingDefect(task.bmp.Width, "jietou", DefectLabelInfoList);
- if (DefectLabelInfoList.Count > 0)
- DefectLabelInfoList = HeBingDefect(task.bmp.Width, "hengdang", DefectLabelInfoList);
- if (DefectLabelInfoList.Count > 0)
- DefectLabelInfoList = HeBingDefect(task.bmp.Width, "jt", DefectLabelInfoList);
- if (DefectLabelInfoList.Count > 0)
- DefectLabelInfoList = HeBingDefect(task.bmp.Width, "hd", DefectLabelInfoList);
- if (DefectLabelInfoList.Count > 0)
- DefectLabelInfoList = HeBingDefect(task.bmp.Width, "bj", DefectLabelInfoList);
- #endregion
- //结果过滤
- #region 结果过滤
-
- step = 8888;
- if (DefectLabelInfoList.Count > 0)
- {
- //降序排序,先得到是否有接头检出
- List<DefectLabelInfo> DefectLabelInfoListByClassID = DefectLabelInfoList.OrderByDescending(t => t.classId).ToList();//降序
- for (int q = 0; q < DefectLabelInfoList.Count; q++)
- {
- //是否满足此产品标准
- if (task.qualifiedLimitList != null && task.qualifiedLimitList.Count > 0)
- {
- qualifiedLimit = task.qualifiedLimitList.FirstOrDefault(m => m.Code == task.labelDic[DefectLabelInfoList[q].classId]);
- if (qualifiedLimit != null)
- {
- //if ((qualifiedLimit.ZXD > 0 && qualifiedLimit.ZXD > confidence)
- // || (qualifiedLimit.ContrastTop + qualifiedLimit.ContrastLower > 0 && x> qualifiedLimit.ContrastLower && x < qualifiedLimit.ContrastTop)
- // || (qualifiedLimit.Area > 0 && qualifiedLimit.Area > cmW * cmH))
- if (DefectLabelInfoList[q].confidence <= qualifiedLimit.ZXD)//confidence > qualifiedLimit.ZXD 是瑕疵 才继续判断下面的两个条件
- {
- task.resultInfo += $" 置信度不满足此产品瑕疵标准,跳过! \n";
- continue;
- }
-
- //下限<对比度<上限:不是瑕疵
- var ContrastTotal = qualifiedLimit.ContrastTop + qualifiedLimit.ContrastLower;
- if (qualifiedLimit.IsOR)
- {
- if (!(
- (qualifiedLimit.Area <= 0 || DefectLabelInfoList[q].cmW * DefectLabelInfoList[q].cmH >= (qualifiedLimit.Area / 100)) ||
- (ContrastTotal <= 0 || (DefectLabelInfoList[q].contrast < qualifiedLimit.ContrastLower || DefectLabelInfoList[q].contrast > qualifiedLimit.ContrastTop))))
- {
- task.resultInfo += $" 不满足此产品瑕疵标准,跳过! \n";
- //WarningEvent?.Invoke(DateTime.Now,WarningEnum.Low, $"判断不是瑕疵:类别ID:{classId}; 置信度({confidence},[{qualifiedLimit.ZXD}]); isOr({qualifiedLimit.IsOR}); 面积({cmW * cmH},[{ qualifiedLimit.Area}]); 对比度({contrast},[{qualifiedLimit.ContrastLower}-{qualifiedLimit.ContrastTop}])");
- continue;
- }
- }
- else
- {
- if (!(
- (qualifiedLimit.Area <= 0 || DefectLabelInfoList[q].cmW * DefectLabelInfoList[q].cmH >= qualifiedLimit.Area / 100) &&
- (ContrastTotal <= 0 || (DefectLabelInfoList[q].contrast < qualifiedLimit.ContrastLower || DefectLabelInfoList[q].contrast > qualifiedLimit.ContrastTop))))
- {
- task.resultInfo += $" 不满足此产品瑕疵标准,跳过! \n";
- //WarningEvent?.Invoke(DateTime.Now,WarningEnum.Low, $"判断不是瑕疵:类别ID:{classId}; 置信度({confidence},[{qualifiedLimit.ZXD}]); isOr({qualifiedLimit.IsOR}); 面积({cmW * cmH},[{ qualifiedLimit.Area}]); 对比度({contrast},[{qualifiedLimit.ContrastLower}-{qualifiedLimit.ContrastTop}])");
- continue;
- }
- }
- if (task.labelDic[DefectLabelInfoList[q].classId] == "jietou")
- haveJieTou = true;
- if (haveJieTou && (task.labelDic[DefectLabelInfoList[q].classId] == "hengdang"))
- {
- task.resultInfo += $" 判断为接头处横档,跳过! \n";
- continue;
- }
- //WarningEvent?.Invoke(DateTime.Now,WarningEnum.Low, $"判断是瑕疵:类别ID:{classId}; 置信度({confidence},[{qualifiedLimit.ZXD}]); isOr({qualifiedLimit.IsOR}); 面积({cmW * cmH},[{ qualifiedLimit.Area}]); 对比度({contrast},[{qualifiedLimit.ContrastLower}-{qualifiedLimit.ContrastTop}])");
- }
- }
- step++;
- //1
- int penLine = 20;
- //打标
- var point1 = new OpenCvSharp.Point((DefectLabelInfoList[q].i % colNum) * image_width + DefectLabelInfoList[q].x - penLine / 2, (DefectLabelInfoList[q].i / colNum) * image_hight + DefectLabelInfoList[q].y - penLine / 2);
- var point2 = new OpenCvSharp.Point(point1.X + DefectLabelInfoList[q].w + penLine / 2, point1.Y + DefectLabelInfoList[q].h + penLine / 2);
- step++;//2
- task.resultInfo += $" 转换到大图坐标(px):p1={point1.X},{point1.Y}; p2={point2.X},{point2.Y}\n";
-
-
-
- Cv2.Rectangle(task.bmpTag, point1, point2, new Scalar(0.0, 0.0, 255.0), penLine);//画打标点
-
- //WarningEvent?.Invoke(DateTime.Now,WarningEnum.Low, $"保存第 {count} 行缺陷信息;");
- int px = (point1.X - task.xw) > 0 ? (point1.X - task.xw) : 0;
- var cmX = Math.Round(px * task.widthRatio / task.cm2px_x, 2);
- var cmY = Math.Round((task.bmp.Height - point1.Y - DefectLabelInfoList[q].h) * task.widthRatio / task.cm2px_y, 2);//外面计Y从右下角为原点
- step++;//3
- task.resultInfo += $" 转换到大图坐标(cm)[widthRatio={task.widthRatio}]:x={cmX},y={cmY}; w={DefectLabelInfoList[q].cmW},h={DefectLabelInfoList[q].cmH}\n";
- task.excelTable.Rows.Add($"{task.photoIndex}", cmX, cmY, DefectLabelInfoList[q].cmW, DefectLabelInfoList[q].cmH, DefectLabelInfoList[q].j + 1, DefectLabelInfoList[q].classId, DefectLabelInfoList[q].confidence, Utils.ContrastToPercent(DefectLabelInfoList[q].contrast));
-
- step++;//4
- //切缺陷小图
- //WarningEvent?.Invoke(DateTime.Now,WarningEnum.Low, $"保存第 {count} 个缺陷小图;");
- int left, top, decX, decY;
- //decX = (DefectLabelInfoList[q].w > 236 ? 20 : 256 - DefectLabelInfoList[q].w) / 2;
- //decY = (DefectLabelInfoList[q].h > 236 ? 20 : 256 - DefectLabelInfoList[q].h) / 2;
- int tdecX = (DefectLabelInfoList[q].w / 2) / 2;
- int tdecY = DefectLabelInfoList[q].w / DefectLabelInfoList[q].h > 4 ? DefectLabelInfoList[q].w / 8 : (DefectLabelInfoList[q].h / 1) / 2;
-
- decX = (DefectLabelInfoList[q].w > 236 ? tdecX : 256 - DefectLabelInfoList[q].w) / 2;
- decY = (DefectLabelInfoList[q].h > 236 ? tdecY : 256 - DefectLabelInfoList[q].h) / 2;
-
- left = point1.X - decX;
- top = point1.Y - decY;
- if (left < 0) left = 0;
- if (top < 0) top = 0;
-
- int width = DefectLabelInfoList[q].w + decX * 2;
- int height = DefectLabelInfoList[q].h + decY * 2;
- if (left + width > task.bmp.Width - 1) width = task.bmp.Width - left - 1;
- if (top + height > task.bmp.Height - 1) height = task.bmp.Height - top - 1;
- step++;//5
- Rect roi = new Rect(left, top, width, height);
- step++;//6
- if (height < 1 || width < 1)
- {
- task.resultInfo += $" 打标到大图坐标Rect(px):left={left},top={top}; width={width},height={height}\n";
- task.resultInfo += $" test point1.Y={point1.Y},h={DefectLabelInfoList[q].h}; top={top},mat.Height={task.bmp.Height}\n================\n";
- WarningEvent?.Invoke(WarningEnum.Normal, task.resultInfo);
- }
-
- //保存
- //string filename = $"{Config.appBasePath}\\temp\\{task.tag}\\{task.tag}_X{mmX.ToString()}_Y{mmY.ToString()}_W{mmW.ToString()}_H{mmH.ToString()}_目标{j + 1}_类别{classId}_置信度{confidence}.bmp";
- //OpenCvSharp.Extensions.BitmapConverter.ToBitmap(new Mat(task.bmp, roi)).Save(filename, ImageFormat.Jpeg);
-
- task.lstDefectBmp.Add(new Mat(task.bmpTag, roi).Clone());
- step++;//7
- }
- }
- #endregion
- step = 99;
- stopwatch.Stop();
- task.stopwatch[3] = stopwatch.ElapsedMilliseconds;
-
- task.isSucceed = true;
-
- //lock (taskDefectOverList)
- //{
- // taskDefectOverList.Add(task);
- // QueueCountEvent?.BeginInvoke(3, taskDefectOverList.Count, null, null);
- //}
-
- callback(task);
- }
- }
- catch (Exception ex)
- {
- WarningEvent?.Invoke(WarningEnum.Low, $"DefectLib taskRun err({step}):" + ex.Message);
- task.isSucceed = false;
- task.resultInfo = ex.Message;
- callback(task);
- }
- Thread.Sleep(5);
- }
- }
- #region 词条合并
- private List<DefectLabelInfo> HeBingDefect(int Width, string label, List<DefectLabelInfo> DefectLabelInfoList)
- {
- int fw = 2000;
- List<DefectLabelInfo> outList = new List<DefectLabelInfo>();
-
- List<DefectLabelInfo> HeBingList = new List<DefectLabelInfo>();
- List<DefectLabelInfo> XcHeBingList = new List<DefectLabelInfo>();
- List<int> xPos = new List<int>();
- List<int> yPos = new List<int>();
- List<double> xZXD = new List<double>();
- List<double> xDBD = new List<double>();
-
- DefectLabelInfo stpoint = DefectLabelInfoList[0];
-
- int colNum = Width / image_width;
- //寻找在一条线上
- for (int q = 0; q < DefectLabelInfoList.Count; q++)
- {
- if (SysMgr.Instance.GetDefectCode()[DefectLabelInfoList[q].classId] == label)
- {
- int max = stpoint.y + fw;
- int min = stpoint.y - fw > 0 ? stpoint.y - fw : 0;
- if (DefectLabelInfoList[q].y >= min && DefectLabelInfoList[q].y <= max)
- {
- HeBingList.Add(DefectLabelInfoList[q]);
- xPos.Add((DefectLabelInfoList[q].i % colNum) * image_width + DefectLabelInfoList[q].x);
- yPos.Add((DefectLabelInfoList[q].i / colNum) * image_hight + DefectLabelInfoList[q].y);
- xZXD.Add(DefectLabelInfoList[q].confidence);
- xDBD.Add(DefectLabelInfoList[q].contrast);
- }
- else
- XcHeBingList.Add(DefectLabelInfoList[q]);
- }
- else
- outList.Add(DefectLabelInfoList[q]);
- }
- //递归下次合并数据
- List<DefectLabelInfo> dg1 = new List<DefectLabelInfo>();
- if (XcHeBingList.Count > 0)
- dg1 = HeBingDefect(Width, label, XcHeBingList);
-
-
- //多个jietou合并
- if (HeBingList.Count > 0)
- {
- var stIt = HeBingList.Find(x => ((x.i % colNum) * image_width + x.x) == xPos.Min());
- var edIt = HeBingList.Find(x => ((x.i % colNum) * image_width + x.x) == xPos.Max());
-
- var stIty = HeBingList.Find(x => ((x.i / colNum) * image_hight + x.y) == yPos.Min());
- var edIty = HeBingList.Find(x => ((x.i / colNum) * image_hight + x.y) == yPos.Max());
-
- var eZXD = HeBingList.Find(x => x.confidence == xZXD.Max());
- double eDBD = 0;
- double DBD = 0;
- for (int i = 0; i < xDBD.Count; i++)
- {
- if (Math.Abs(xDBD[i] - 1) >= eDBD)
- {
- eDBD = Math.Abs(xDBD[i] - 1);
- DBD = xDBD[i];
- }
- }
- int newW = Math.Abs(((edIt.i % colNum) * image_width + edIt.x) - ((stIt.i % colNum) * image_width + stIt.x)) + edIt.w;
- int newh = Math.Abs(((edIt.i / colNum) * image_hight + edIt.y) - ((stIt.i / colNum) * image_hight + stIt.y)) + edIt.h;
- outList.Add(new DefectLabelInfo()
- {
- x = stIt.x,
- y = edIt.y,
- w = newW, //多图叠加
- h = newh, //多图叠加
- classId = eZXD.classId,
- confidence = eZXD.confidence,
- contrast = DBD,
- cmH = Math.Round(edIt.h * 1.0 / ConfMgr.Instance.SysConfigParams.Cm2px_y, 2),
- cmW = Math.Round(newW * 1.0 / ConfMgr.Instance.SysConfigParams.Cm2px_x, 2),
- i = stIt.i,
- j = stIt.j,
- });
- }
-
- outList = outList.Concat(dg1).ToList<DefectLabelInfo>();//保留重复项
- return outList;
- }
- #endregion
-
- #region 结果回调
- private void callback(DefectTask 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 = (DefectTask)o;
- task.finishEvent(task);
- });
- #endregion
-
- #region 处理队列
- public string GetDefectInfo()
- {
- string str = "";
- int cnt1, cnt2, cnt3;
- lock (taskList)
- {
- cnt1 = taskList.Count;
- }
- lock (taskOperationList)
- {
- cnt2 = taskOperationList.Count;
- }
- lock (taskMakeTagList)
- {
- cnt3 = taskMakeTagList.Count;
- }
- str = $"预处理:{cnt1},推理:{cnt2},打标:{cnt3}";
- return str; ;
- }
-
- public void add(DefectTask task)
- {
- lock (taskList)
- {
- taskList.Add(task);
- QueueCountEvent?.BeginInvoke(0, taskList.Count, null, null);
- }
- }
-
-
- private DefectTask 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);
- QueueCountEvent?.BeginInvoke(0, taskList.Count, null, null);
- return task;
- }
- }
- private DefectTask pop2()
- {
- lock (taskOperationList)
- {
- if (taskOperationList.Count < 1)
- return null;
-
- //int index = 0;// taskList.FindIndex(p => { return p.isSync; });
- //if (index < 0) index = 0;
- var task = taskOperationList[0];
- taskOperationList.RemoveAt(0);
- QueueCountEvent?.BeginInvoke(1, taskOperationList.Count, null, null);
- return task;
- }
- }
- private DefectTask pop3()
- {
- lock (taskMakeTagList)
- {
- if (taskMakeTagList.Count < 1)
- return null;
-
- //int index = 0;// taskList.FindIndex(p => { return p.isSync; });
- //if (index < 0) index = 0;
- var task = taskMakeTagList[0];
- taskMakeTagList.RemoveAt(0);
- QueueCountEvent?.BeginInvoke(2, taskMakeTagList.Count, null, null);
- return task;
- }
- }
- private DefectTask pop4()
- {
- lock (taskDefectOverList)
- {
- if (taskDefectOverList.Count < 1)
- return null;
-
- //int index = 0;// taskList.FindIndex(p => { return p.isSync; });
- //if (index < 0) index = 0;
- var task = taskDefectOverList[0];
- taskDefectOverList.RemoveAt(0);
- QueueCountEvent?.BeginInvoke(3, taskDefectOverList.Count, null, null);
- return task;
- }
- }
- #endregion
-
- public void Dispose()
- {
- stop();
- }
-
- private class DefectLabelInfo
- {
- public int x { get; set; }
- public int y { get; set; }
- public int w { get; set; }
- public int h { get; set; }
- public int classId { get; set; }
- public double confidence { get; set; } //置信度
- public double contrast { get; set; }//对比度
-
- public double cmW { get; set; }
- public double cmH { get; set; }
-
- public int i { get; set; }//小图index
- public int j { get; set; }//缺陷index
- }
- }
-
- public class DefectTask
- {
- public DefectTask()
- {
- // 创建一个 DataTable 对象来存储数据
- excelTable = new DataTable("MyData");
- // 添加列到 DataTable
- excelTable.Columns.Add("FileName", typeof(string));
- excelTable.Columns.Add("X", typeof(decimal));
- excelTable.Columns.Add("Y", typeof(decimal));
- excelTable.Columns.Add("W", typeof(decimal));
- excelTable.Columns.Add("H", typeof(decimal));
- excelTable.Columns.Add("目标", typeof(int));
- excelTable.Columns.Add("类别", typeof(int));
- excelTable.Columns.Add("置信度", typeof(decimal));
- excelTable.Columns.Add("对比度", typeof(decimal));
- // 向 DataTable 中添加数据行
- //excelTable.Rows.Add("John Doe", 30);
- //excelTable.Rows.Add("Jane Smith", 25);
- }
- /// <summary>
- /// 处理参数
- /// </summary>
- public int expand_pixel;
- public int cm2px_x;
- public int cm2px_y;
-
- public Dictionary<int, string> labelDic;
- /// <summary>
- /// 模型名字
- /// </summary>
- public string modelName;
-
- public Models.Records record;
- //public string bmpPath;//源图路径(仅目录)
- /// <summary>
- /// 源图(resize后的)
- /// </summary>
- public Mat bmp;
- //public Mat bmpBgr2rgb=new Mat();
-
- public System.Drawing.Size resize = new System.Drawing.Size(224, 224);
- //public Mat resizeBmp;//resize后 BGR2RGB图,只用于识别
- public Mat bmpTag;
- /// <summary>
- /// 图片索引0-n
- /// </summary>
- public int photoIndex;//excel中对应的图像路径标识
- public float widthRatio;//宽度比例,resize前/resize后
- //切割后
- public Mat[] bmps_cut;
-
- //用于比对参数 }//置信度 面积 对比度
- public List<QualifiedLimit> qualifiedLimitList;
-
- //推理后结果用于打标
- public float[] output;
- public int[] output_num;
-
- //
- /// <summary>
- /// 完成后回调
- /// </summary>
- public Action<DefectTask> finishEvent;
- //==结果返回
- public bool isSucceed;//转换是否成功
- public string resultInfo = "";//成功或失败信息
-
- public List<Mat> lstDefectBmp = new List<Mat>();
- /// <summary>
- /// fileIndex,x_mm,y_mm,w_mm,h_mm,目标,类别ID,置信度
- /// </summary>
- public DataTable excelTable = new DataTable();
- public long[] stopwatch = new long[6];
-
- /// <summary>
- /// 等比例填充的宽度
- /// </summary>
- public int xw;
-
- /// <summary>
- /// 当前图像计米器位置
- /// </summary>
- public double CurrDis;
- }
- }
|