修改板卡
This commit is contained in:
		| @@ -5,6 +5,26 @@ | |||||||
|     <ImplicitUsings>enable</ImplicitUsings> |     <ImplicitUsings>enable</ImplicitUsings> | ||||||
|     <Nullable>enable</Nullable> |     <Nullable>enable</Nullable> | ||||||
|     <Platforms>AnyCPU;X64</Platforms> |     <Platforms>AnyCPU;X64</Platforms> | ||||||
|  |     <AllowUnsafeBlocks>True</AllowUnsafeBlocks> | ||||||
|   </PropertyGroup> |   </PropertyGroup> | ||||||
|  |  | ||||||
|  |   <ItemGroup> | ||||||
|  |     <Folder Include="Helper\" /> | ||||||
|  |   </ItemGroup> | ||||||
|  |  | ||||||
|  |   <ItemGroup> | ||||||
|  |     <PackageReference Include="OpenCvSharp4" Version="4.10.0.20241108" /> | ||||||
|  |     <PackageReference Include="OpenCvSharp4.Extensions" Version="4.10.0.20241108" /> | ||||||
|  |     <PackageReference Include="OpenCvSharp4.runtime.win" Version="4.10.0.20241108" /> | ||||||
|  |   </ItemGroup> | ||||||
|  |  | ||||||
|  |   <ItemGroup> | ||||||
|  |     <Reference Include="halcondotnet"> | ||||||
|  |       <HintPath>..\x64\Debug\halcondotnet.dll</HintPath> | ||||||
|  |     </Reference> | ||||||
|  |     <Reference Include="hdevenginedotnet"> | ||||||
|  |       <HintPath>..\x64\Debug\hdevenginedotnet.dll</HintPath> | ||||||
|  |     </Reference> | ||||||
|  |   </ItemGroup> | ||||||
|  |  | ||||||
| </Project> | </Project> | ||||||
|   | |||||||
							
								
								
									
										39
									
								
								DH.Commons/GlobalVar.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										39
									
								
								DH.Commons/GlobalVar.cs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,39 @@ | |||||||
|  |  | ||||||
|  |  | ||||||
|  | namespace XKRS.Common.Model | ||||||
|  | { | ||||||
|  |     public static class GlobalVar | ||||||
|  |     { | ||||||
|  |  | ||||||
|  |         //public const string SEPERATOR = "|"; | ||||||
|  |  | ||||||
|  |         //public static ContainerBuilder Builder { get; set; } = new ContainerBuilder(); | ||||||
|  |  | ||||||
|  |         //private static object containerLock = new object(); | ||||||
|  |  | ||||||
|  |         //private static IContainer container = null; | ||||||
|  |         //public static IContainer Container | ||||||
|  |         //{ | ||||||
|  |         //    get | ||||||
|  |         //    { | ||||||
|  |         //        if (container == null) | ||||||
|  |         //        { | ||||||
|  |         //            lock (containerLock) | ||||||
|  |         //            { | ||||||
|  |         //                if (container == null) | ||||||
|  |         //                { | ||||||
|  |         //                    container = Builder.Build(); | ||||||
|  |         //                } | ||||||
|  |         //            } | ||||||
|  |         //        } | ||||||
|  |  | ||||||
|  |         //        return container; | ||||||
|  |         //    } | ||||||
|  |         //} | ||||||
|  |  | ||||||
|  |         //public static void InitialAutoFac() | ||||||
|  |         //{ | ||||||
|  |         //    Container = Builder.Build(); | ||||||
|  |         //} | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										677
									
								
								DH.Commons/Helper/HDevEngineTool.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										677
									
								
								DH.Commons/Helper/HDevEngineTool.cs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,677 @@ | |||||||
|  | using HalconDotNet; | ||||||
|  | using System.Diagnostics; | ||||||
|  | using System.Drawing; | ||||||
|  | using System.Drawing.Imaging; | ||||||
|  | using System.Runtime.ExceptionServices; | ||||||
|  | using System.Runtime.InteropServices; | ||||||
|  |  | ||||||
|  | namespace XKRS.Common.Model | ||||||
|  | { | ||||||
|  |     public class HDevEngineTool : IDisposable | ||||||
|  |     { | ||||||
|  |         #region 常量 | ||||||
|  |  | ||||||
|  |         // path of external procedures | ||||||
|  |         readonly string ProcedurePath = Environment.CurrentDirectory + "\\Vision\\"; | ||||||
|  |  | ||||||
|  |         #endregion | ||||||
|  |  | ||||||
|  |         #region 成员变量 | ||||||
|  |  | ||||||
|  |         /// <summary> | ||||||
|  |         /// 处理过程名 | ||||||
|  |         /// </summary> | ||||||
|  |         public string ProcedureName; | ||||||
|  |  | ||||||
|  |         /// <summary> | ||||||
|  |         /// hdev程序启动引擎 | ||||||
|  |         /// </summary> | ||||||
|  |         private readonly HDevEngine myEngine; | ||||||
|  |  | ||||||
|  |         /// <summary> | ||||||
|  |         /// 过程载入工具 .hdvp | ||||||
|  |         /// </summary> | ||||||
|  |         private HDevProcedureCall procedureCall; | ||||||
|  |  | ||||||
|  |         /// <summary> | ||||||
|  |         /// 程序运行是否成功 | ||||||
|  |         /// </summary> | ||||||
|  |         public bool IsSuccessful { get; set; } = false; | ||||||
|  |  | ||||||
|  |         /// <summary> | ||||||
|  |         /// 控制参数字典 | ||||||
|  |         /// </summary> | ||||||
|  |         public Dictionary<string, HTuple> InputTupleDic { get; set; } | ||||||
|  |  | ||||||
|  |         /// <summary> | ||||||
|  |         /// 图形参数字典 | ||||||
|  |         /// </summary> | ||||||
|  |         public Dictionary<string, HObject> InputImageDic { get; set; } | ||||||
|  |  | ||||||
|  |         #endregion | ||||||
|  |  | ||||||
|  |         #region 初始化 | ||||||
|  |         /// <summary> | ||||||
|  |         /// 实例化 默认搜索路径为: 启动路径//Vision// | ||||||
|  |         /// </summary> | ||||||
|  |         public HDevEngineTool() | ||||||
|  |         { | ||||||
|  |             ProcedureName = ""; | ||||||
|  |             myEngine = new HDevEngine(); | ||||||
|  |             myEngine.SetProcedurePath(ProcedurePath); | ||||||
|  |  | ||||||
|  |             InputImageDic = new Dictionary<string, HObject>(); | ||||||
|  |             InputTupleDic = new Dictionary<string, HTuple>(); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         /// <summary> | ||||||
|  |         /// 实例化 | ||||||
|  |         /// </summary> | ||||||
|  |         /// <param name="path">外部函数搜索路径</param> | ||||||
|  |         public HDevEngineTool(string path) | ||||||
|  |         { | ||||||
|  |             myEngine = new HDevEngine(); | ||||||
|  |             myEngine.SetProcedurePath(path); | ||||||
|  |  | ||||||
|  |             InputImageDic = new Dictionary<string, HObject>(); | ||||||
|  |             InputTupleDic = new Dictionary<string, HTuple>(); | ||||||
|  |         } | ||||||
|  |         #endregion | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  |         /// <summary> | ||||||
|  |         /// 设置函数运行所需参数 | ||||||
|  |         /// </summary> | ||||||
|  |         /// <param name="_tupleDictionary">控制参数</param> | ||||||
|  |         /// <param name="_imageDictionary">图形参数</param> | ||||||
|  |         public void SetDictionary(Dictionary<string, HTuple> _tupleDictionary, Dictionary<string, HObject> _imageDictionary) | ||||||
|  |         { | ||||||
|  |             InputTupleDic = _tupleDictionary; | ||||||
|  |             InputImageDic = _imageDictionary; | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  |         /// <summary> | ||||||
|  |         /// 载入过程 .hdvp | ||||||
|  |         /// </summary> | ||||||
|  |         /// <param name="procedureName">过程名</param> | ||||||
|  |         public void LoadProcedure(string procedureName) | ||||||
|  |         { | ||||||
|  |             ProcedureName = procedureName; | ||||||
|  |             try | ||||||
|  |             { | ||||||
|  |                 HDevProcedure procedure = new HDevProcedure(procedureName); | ||||||
|  |                 procedureCall = new HDevProcedureCall(procedure); | ||||||
|  |             } | ||||||
|  |             catch (HDevEngineException Ex) | ||||||
|  |             { | ||||||
|  |                 Trace.TraceInformation("HDevProgram {0} Load fail ,Error Line : {1}, Line number: {2}, Halcon error number : {3}", Ex.ProcedureName, Ex.LineText, Ex.LineNumber, Ex.HalconError); | ||||||
|  |                 return; | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  |         /// <summary> | ||||||
|  |         /// 执行过程 | ||||||
|  |         /// </summary> | ||||||
|  |         [HandleProcessCorruptedStateExceptions] | ||||||
|  |         public bool RunProcedure(out string errorMsg, out int timeElasped) | ||||||
|  |         { | ||||||
|  |             //lock (_runLock) | ||||||
|  |             { | ||||||
|  |                 errorMsg = ""; | ||||||
|  |                 Stopwatch sw = new Stopwatch(); | ||||||
|  |                 sw.Start(); | ||||||
|  |                 try | ||||||
|  |                 { | ||||||
|  |                     foreach (KeyValuePair<string, HTuple> pair in InputTupleDic) | ||||||
|  |                     { | ||||||
|  |                         procedureCall.SetInputCtrlParamTuple(pair.Key, pair.Value); | ||||||
|  |                     } | ||||||
|  |  | ||||||
|  |                     foreach (KeyValuePair<string, HObject> pair in InputImageDic) | ||||||
|  |                     { | ||||||
|  |                         procedureCall.SetInputIconicParamObject(pair.Key, pair.Value); | ||||||
|  |                     } | ||||||
|  |  | ||||||
|  |                     procedureCall.Execute(); | ||||||
|  |  | ||||||
|  |                     IsSuccessful = true; | ||||||
|  |                 } | ||||||
|  |                 catch (HDevEngineException ex) | ||||||
|  |                 { | ||||||
|  |                     IsSuccessful = false; | ||||||
|  |                     errorMsg = $"HDevProgram {ex.ProcedureName} Run fail , Line number: {ex.LineNumber}, Halcon error number : {ex.HalconError},ex:{ex.Message}"; | ||||||
|  |                 } | ||||||
|  |                 finally | ||||||
|  |                 { | ||||||
|  |                     sw.Stop(); | ||||||
|  |                     timeElasped = (int)sw.ElapsedMilliseconds; | ||||||
|  |                 } | ||||||
|  |                 return IsSuccessful; | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         object _runLock = new object(); | ||||||
|  |         /// <summary> | ||||||
|  |         /// 执行过程 | ||||||
|  |         /// </summary> | ||||||
|  |         public Tuple<bool, Dictionary<string, HTuple>, Dictionary<string, HObject>, string, int> RunProcedure(Dictionary<string, HTuple> inputHTupleDict, Dictionary<string, HObject> inputImgDict, List<string> outputHTuples = null, List<string> outputObjs = null) | ||||||
|  |         { | ||||||
|  |             lock (_runLock) | ||||||
|  |             { | ||||||
|  |                 string errorMsg = ""; | ||||||
|  |                 int timeElasped = 0; | ||||||
|  |                 bool result = false; | ||||||
|  |                 Dictionary<string, HTuple> outputHTupleDict = new Dictionary<string, HTuple>(); | ||||||
|  |                 Dictionary<string, HObject> outputObjDict = new Dictionary<string, HObject>(); | ||||||
|  |  | ||||||
|  |                 Stopwatch sw = new Stopwatch(); | ||||||
|  |                 sw.Start(); | ||||||
|  |                 try | ||||||
|  |                 { | ||||||
|  |                     if (inputHTupleDict != null && inputHTupleDict.Count > 0) | ||||||
|  |                     { | ||||||
|  |                         foreach (KeyValuePair<string, HTuple> pair in inputHTupleDict) | ||||||
|  |                         { | ||||||
|  |                             procedureCall.SetInputCtrlParamTuple(pair.Key, pair.Value); | ||||||
|  |                         } | ||||||
|  |                     } | ||||||
|  |  | ||||||
|  |                     if (InputImageDic != null && inputImgDict.Count > 0) | ||||||
|  |                     { | ||||||
|  |                         foreach (KeyValuePair<string, HObject> pair in inputImgDict) | ||||||
|  |                         { | ||||||
|  |                             procedureCall.SetInputIconicParamObject(pair.Key, pair.Value); | ||||||
|  |                         } | ||||||
|  |                     } | ||||||
|  |  | ||||||
|  |                     procedureCall.Execute(); | ||||||
|  |  | ||||||
|  |                     result = true; | ||||||
|  |                 } | ||||||
|  |                 catch (HDevEngineException ex) | ||||||
|  |                 { | ||||||
|  |                     result = false; | ||||||
|  |                     errorMsg += $"HDevProgram {ex.ProcedureName} Run fail , Line number: {ex.LineNumber}, Halcon error number : {ex.HalconError},ex:{ex.Message}"; | ||||||
|  |                 } | ||||||
|  |                 finally | ||||||
|  |                 { | ||||||
|  |                     sw.Stop(); | ||||||
|  |                     timeElasped = (int)sw.ElapsedMilliseconds; | ||||||
|  |                 } | ||||||
|  |  | ||||||
|  |                 if (result) | ||||||
|  |                 { | ||||||
|  |                     if (outputHTuples != null && outputHTuples.Count > 0) | ||||||
|  |                     { | ||||||
|  |                         outputHTuples.ForEach(t => | ||||||
|  |                         { | ||||||
|  |                             try | ||||||
|  |                             { | ||||||
|  |                                 outputHTupleDict[t] = procedureCall.GetOutputCtrlParamTuple(t); | ||||||
|  |                             } | ||||||
|  |                             catch (Exception ex) | ||||||
|  |                             { | ||||||
|  |                                 result = false; | ||||||
|  |                                 errorMsg += $"\r\n获取{t}结果异常:{ex.Message}"; | ||||||
|  |  | ||||||
|  |                                 outputHTupleDict[t] = null; | ||||||
|  |                             } | ||||||
|  |                         }); | ||||||
|  |                     } | ||||||
|  |  | ||||||
|  |                     if (outputObjs != null && outputObjs.Count > 0) | ||||||
|  |                     { | ||||||
|  |                         outputObjs.ForEach(t => | ||||||
|  |                         { | ||||||
|  |                             try | ||||||
|  |                             { | ||||||
|  |                                 outputObjDict[t] = procedureCall.GetOutputIconicParamObject(t); | ||||||
|  |                             } | ||||||
|  |                             catch (Exception ex) | ||||||
|  |                             { | ||||||
|  |                                 result = false; | ||||||
|  |                                 errorMsg += $"\r\n获取{t}结果异常:{ex.Message}"; | ||||||
|  |  | ||||||
|  |                                 outputObjDict[t] = null; | ||||||
|  |                             } | ||||||
|  |                         }); | ||||||
|  |                     } | ||||||
|  |                 } | ||||||
|  |                 Tuple<bool, Dictionary<string, HTuple>, Dictionary<string, HObject>, string, int> ret = new Tuple<bool, Dictionary<string, HTuple>, Dictionary<string, HObject>, string, int>(result, outputHTupleDict, outputObjDict, errorMsg, timeElasped); | ||||||
|  |                 return ret; | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         public HTuple GetResultTuple(string key) | ||||||
|  |         { | ||||||
|  |             try | ||||||
|  |             { | ||||||
|  |                 if (IsSuccessful) | ||||||
|  |                 { | ||||||
|  |                     return procedureCall.GetOutputCtrlParamTuple(key); | ||||||
|  |                 } | ||||||
|  |                 else | ||||||
|  |                 { | ||||||
|  |                     return new HTuple(); | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |             catch (Exception ex) | ||||||
|  |             { | ||||||
|  |                 return new HTuple(); | ||||||
|  |             } | ||||||
|  |  | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         public HObject GetResultObject(string key, bool ignoreError = false) | ||||||
|  |         { | ||||||
|  |             try | ||||||
|  |             { | ||||||
|  |                 if (ignoreError || IsSuccessful) | ||||||
|  |                 { | ||||||
|  |                     return procedureCall.GetOutputIconicParamObject(key); | ||||||
|  |                 } | ||||||
|  |                 else | ||||||
|  |                 { | ||||||
|  |                     return new HObject(); | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |             catch (Exception ex) | ||||||
|  |             { | ||||||
|  |                 return new HObject(); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         public void Dispose() | ||||||
|  |         { | ||||||
|  |             procedureCall?.Dispose(); | ||||||
|  |             myEngine?.Dispose(); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public static class HalconHelper | ||||||
|  |     { | ||||||
|  |         [DllImport("kernel32.dll", EntryPoint = "CopyMemory", SetLastError = false)] | ||||||
|  |         public static extern void CopyMemory(IntPtr dest, IntPtr src, uint count); | ||||||
|  |  | ||||||
|  |         public static HImage Convert8GrayBitmapToHImage(this Bitmap bmp) | ||||||
|  |         { | ||||||
|  |             HImage himage = new HImage(); | ||||||
|  |             try | ||||||
|  |             { | ||||||
|  |                 //判断输入图像不为null | ||||||
|  |                 if (bmp == null) | ||||||
|  |                 { | ||||||
|  |                     return null; | ||||||
|  |                 } | ||||||
|  |  | ||||||
|  |                 { | ||||||
|  |                     //重绘himage | ||||||
|  |                     //HImage curImage = new HImage(); | ||||||
|  |                     BitmapData bmpData = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height), ImageLockMode.ReadOnly, PixelFormat.Format8bppIndexed); | ||||||
|  |                     himage.GenImage1("byte", bmp.Width, bmp.Height, bmpData.Scan0); | ||||||
|  |                     bmp.UnlockBits(bmpData); | ||||||
|  |                     //himage = curImage; | ||||||
|  |                 } | ||||||
|  |                 return himage; | ||||||
|  |             } | ||||||
|  |             catch (Exception e) | ||||||
|  |             { | ||||||
|  |                 return null; | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         public static Bitmap ConvertHImageToBitmap(this HObject hImage) | ||||||
|  |         { | ||||||
|  |             HOperatorSet.CountChannels(hImage, out HTuple chanels); | ||||||
|  |             if (chanels.I == 1) | ||||||
|  |             { | ||||||
|  |                 return hImage.ConvertHImageTo8GrayBitmap(); | ||||||
|  |             } | ||||||
|  |             else | ||||||
|  |             { | ||||||
|  |                 return hImage.ConvertHImageToRGBBitmap(); | ||||||
|  |                 //return hImage.HObject2BitmapRGB(); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         public static Bitmap HObject2BitmapRGB(this HObject hObject) | ||||||
|  |         { | ||||||
|  |             ////获取图像尺寸 | ||||||
|  |             HTuple width0, height0, type, width, height; | ||||||
|  |             //获取图像尺寸 | ||||||
|  |             HOperatorSet.GetImageSize(hObject, out width0, out height0); | ||||||
|  |             // 创建交错格式图像 | ||||||
|  |             HOperatorSet.InterleaveChannels(hObject, out HObject InterImage, "argb", "match", 255);  //"rgb", 4 * width0, 0     "argb", "match", 255 | ||||||
|  |  | ||||||
|  |             //获取交错格式图像指针 | ||||||
|  |             HOperatorSet.GetImagePointer1(InterImage, out HTuple Pointer, out type, out width, out height); | ||||||
|  |             IntPtr ptr = Pointer; | ||||||
|  |             //构建新Bitmap图像 | ||||||
|  |             Bitmap res32 = new Bitmap(width / 4, height, width, PixelFormat.Format32bppArgb, ptr);  // Format32bppArgb     Format24bppRgb | ||||||
|  |  | ||||||
|  |             //32位Bitmap转24位 | ||||||
|  |             var res24 = new Bitmap(res32.Width, res32.Height, PixelFormat.Format24bppRgb); | ||||||
|  |             Graphics graphics = Graphics.FromImage(res24); | ||||||
|  |             graphics.DrawImage(res32, new Rectangle(0, 0, res32.Width, res32.Height)); | ||||||
|  |  | ||||||
|  |             return res24; | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         public static Bitmap ConvertHImageTo8GrayBitmap(this HObject hImage) | ||||||
|  |         { | ||||||
|  |             try | ||||||
|  |             { | ||||||
|  |                 HTuple type, width, height, pointer; | ||||||
|  |                 HOperatorSet.GetImagePointer1(hImage, out pointer, out type, out width, out height); | ||||||
|  |  | ||||||
|  |                 Bitmap bmp = new Bitmap(width.I, height.I, PixelFormat.Format8bppIndexed); | ||||||
|  |                 ColorPalette pal = bmp.Palette; | ||||||
|  |                 for (int i = 0; i <= 255; i++) | ||||||
|  |                 { | ||||||
|  |                     pal.Entries[i] = Color.FromArgb(255, i, i, i); | ||||||
|  |                 } | ||||||
|  |                 bmp.Palette = pal; | ||||||
|  |  | ||||||
|  |                 BitmapData bitmapData = bmp.LockBits(new Rectangle(0, 0, width, height), ImageLockMode.WriteOnly, PixelFormat.Format8bppIndexed); | ||||||
|  |  | ||||||
|  |                 if (width % 4 == 0) | ||||||
|  |                 { | ||||||
|  |                     CopyMemory(bitmapData.Scan0, (IntPtr)pointer.D, (uint)(bitmapData.Stride * height.I)); | ||||||
|  |                 } | ||||||
|  |                 else | ||||||
|  |                 { | ||||||
|  |                     Parallel.For(0, height.I, h => | ||||||
|  |                     { | ||||||
|  |                         CopyMemory(bitmapData.Scan0 + h * bitmapData.Stride, (IntPtr)(pointer.D + h * width.I), (uint)width.I); | ||||||
|  |                     }); | ||||||
|  |                 } | ||||||
|  |  | ||||||
|  |                 bmp.UnlockBits(bitmapData); | ||||||
|  |                 return bmp; | ||||||
|  |             } | ||||||
|  |             catch (Exception ex) | ||||||
|  |             { | ||||||
|  |                 return null; | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         public static Bitmap ConvertHImageToRGBBitmap(this HObject hImage) | ||||||
|  |         { | ||||||
|  |             try | ||||||
|  |             { | ||||||
|  |                 HOperatorSet.GetImagePointer3(hImage, out HTuple pointRed, out HTuple pointGreen, out HTuple pointBlue, out HTuple type, out HTuple width, out HTuple height); | ||||||
|  |                 Bitmap image = new Bitmap(width.I, height.I, PixelFormat.Format24bppRgb); | ||||||
|  |                 BitmapData imageData = image.LockBits(new Rectangle(0, 0, width.I, height.I), ImageLockMode.ReadWrite, image.PixelFormat); | ||||||
|  |                 IntPtr pR = (IntPtr)pointRed.D; | ||||||
|  |                 IntPtr pG = (IntPtr)pointGreen.D; | ||||||
|  |                 IntPtr pB = (IntPtr)pointBlue.D; | ||||||
|  |                 Parallel.For(0, imageData.Height, h => | ||||||
|  |                 { | ||||||
|  |                     Parallel.For(0, imageData.Width, w => | ||||||
|  |                     { | ||||||
|  |                         int dest = h * imageData.Stride + w * 3; | ||||||
|  |                         int source = h * imageData.Width + w; | ||||||
|  |  | ||||||
|  |                         Marshal.WriteByte(imageData.Scan0, dest, Marshal.ReadByte(pB, source)); | ||||||
|  |                         Marshal.WriteByte(imageData.Scan0, dest + 1, Marshal.ReadByte(pG, source)); | ||||||
|  |                         Marshal.WriteByte(imageData.Scan0, dest + 2, Marshal.ReadByte(pR, source)); | ||||||
|  |                     }); | ||||||
|  |                 }); | ||||||
|  |  | ||||||
|  |                 image.UnlockBits(imageData); | ||||||
|  |                 return image; | ||||||
|  |             } | ||||||
|  |             catch (Exception exc) | ||||||
|  |             { | ||||||
|  |                 return null; | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         public static Bitmap ConvertHImageTo16GrayBitmap(this HImage originHImage) | ||||||
|  |         { | ||||||
|  |             //IntPtr pointer = hImage.GetImagePointer1(out string type, out int width, out int height); | ||||||
|  |  | ||||||
|  |             //int widthIn4 = (int)Math.Ceiling(width / 4.0) * 4; | ||||||
|  |  | ||||||
|  |             ////Bitmap bmp = new Bitmap(widthIn4, height, PixelFormat.Format48bppRgb); | ||||||
|  |             //Bitmap showImage = new Bitmap(widthIn4, height, PixelFormat.Format48bppRgb); | ||||||
|  |  | ||||||
|  |             //Rectangle rect = new Rectangle(0, 0, widthIn4, height); | ||||||
|  |             ////BitmapData bitmapData = bmp.LockBits(rect, ImageLockMode.WriteOnly, PixelFormat.Format48bppRgb); | ||||||
|  |             //BitmapData showImageData = showImage.LockBits(rect, ImageLockMode.WriteOnly, PixelFormat.Format48bppRgb); | ||||||
|  |             //unsafe | ||||||
|  |             //{ | ||||||
|  |             //    byte* data = (byte*)pointer; | ||||||
|  |             //    //byte* bitmapBuffer = (byte*)bitmapData.Scan0; | ||||||
|  |             //    byte* showBitmapBuffer = (byte*)showImageData.Scan0; | ||||||
|  |  | ||||||
|  |             //    Parallel.For(0, width * height, i => | ||||||
|  |             //    { | ||||||
|  |             //        int index = (i + 1) % width + widthIn4 * ((int)Math.Floor((double)(i + 1) / width)) - 1; | ||||||
|  |  | ||||||
|  |             //        //showBitmapBuffer[index * 6] = bitmapBuffer[index * 6] = data[i * 2]; | ||||||
|  |             //        //showBitmapBuffer[index * 6 + 1] = bitmapBuffer[index * 6 + 1] = data[i * 2 + 1]; | ||||||
|  |             //        showBitmapBuffer[index * 6] = data[i * 2]; | ||||||
|  |             //        showBitmapBuffer[index * 6 + 1] = data[i * 2 + 1]; | ||||||
|  |             //    }); | ||||||
|  |             //} | ||||||
|  |  | ||||||
|  |             ////bmp.UnlockBits(bitmapData); | ||||||
|  |             //showImage.UnlockBits(showImageData); | ||||||
|  |  | ||||||
|  |             //return showImage; | ||||||
|  |  | ||||||
|  |             // dev_set_draw('margin') | ||||||
|  |             //read_image(Image, '0.tif') | ||||||
|  |  | ||||||
|  |             HImage hImage = originHImage.Clone(); | ||||||
|  |  | ||||||
|  |             //* 如果16位图像非常暗的话,建议在这一步进行提亮,因为后面8位图像大幅度提亮易造成色阶断裂,出现不连续的像素块 | ||||||
|  |             // * scale_image(Image, Image, 25, 0) | ||||||
|  |             //hImage = hImage.ScaleImage(25.0, 0.0); | ||||||
|  |  | ||||||
|  |             //get_domain(Image, rectangle) | ||||||
|  |             //* 获取全图中像素灰度值的最大和最小值 | ||||||
|  |             //min_max_gray(rectangle, Image, 0, Min, Max, range) | ||||||
|  |             hImage.MinMaxGray(hImage.GetDomain(), 0, out double min, out double max, out double range); | ||||||
|  |  | ||||||
|  |             //* 将16位图的灰度值映射到0 - 255上 | ||||||
|  |             double mult = 255.0 / (max - min); | ||||||
|  |             double add = -mult * min; | ||||||
|  |             hImage = hImage.ScaleImage(mult, add); | ||||||
|  |  | ||||||
|  |             //* 转换为'byte'类型 | ||||||
|  |             //convert_image_type(Image_scaled, ImageConverted, 'byte') | ||||||
|  |             hImage = hImage.ConvertImageType("byte"); | ||||||
|  |  | ||||||
|  |             Bitmap showImage = hImage.ConvertHImageTo8GrayBitmap(); | ||||||
|  |  | ||||||
|  |             hImage.Dispose(); | ||||||
|  |  | ||||||
|  |             return showImage; | ||||||
|  |  | ||||||
|  |             //* 如果转换以后图像整体对比度太低的话,可以提高对比度(这里是对8位图像处理) | ||||||
|  |             //Min:= 20 | ||||||
|  |             //Max:= 160 | ||||||
|  |             //Mult:= 255.0 / (Max - Min) | ||||||
|  |             //Add:= -Mult * Min | ||||||
|  |             //scale_image(ImageConverted, ImageConverted_scaled, Mult, Add) | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         public static List<double> HTupleToDouble(this HTuple tuple) | ||||||
|  |         { | ||||||
|  |             List<double> list = new List<double>(); | ||||||
|  |  | ||||||
|  |             for (int i = 0; i < tuple.Length; i++) | ||||||
|  |             { | ||||||
|  |                 list.Add(tuple[i].D); | ||||||
|  |             } | ||||||
|  |  | ||||||
|  |             return list; | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  |         public static HImage ConvertHObjectToHImage(this HObject obj) | ||||||
|  |         { | ||||||
|  |             HOperatorSet.CountChannels(obj, out HTuple channels); | ||||||
|  |  | ||||||
|  |             HImage img = new HImage(); | ||||||
|  |             if (channels.I == 1) | ||||||
|  |             { | ||||||
|  |                 HTuple pointer, type, width, height; | ||||||
|  |                 HOperatorSet.GetImagePointer1(obj, out pointer, out type, out width, out height); | ||||||
|  |  | ||||||
|  |                 img.GenImage1(type, width, height, pointer); | ||||||
|  |             } | ||||||
|  |             else | ||||||
|  |             { | ||||||
|  |                 HTuple pRed, pGreen, pBlue, type, width, height; | ||||||
|  |                 HOperatorSet.GetImagePointer3(obj, out pRed, out pGreen, out pBlue, out type, out width, out height); | ||||||
|  |  | ||||||
|  |                 img.GenImage3(type, width, height, pRed, pGreen, pBlue); | ||||||
|  |             } | ||||||
|  |  | ||||||
|  |             return img; | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         #region 灰度图转换为伪彩图 | ||||||
|  |         public static Bitmap ConvertGrayImageToPesudoColorfulImage(this HImage hImage, double max = 0, double min = 0, double zoom = 1, bool isShowHeightTip = false, int zResolution = 100000) | ||||||
|  |         { | ||||||
|  |             hImage.GetImageSize(out int width, out int height); | ||||||
|  |             hImage.MinMaxGray(new HRegion(0.0, 0.0, width, height), 3, out HTuple roiMin, out HTuple roiMax, out _); | ||||||
|  |  | ||||||
|  |             if (max == 0) | ||||||
|  |             { | ||||||
|  |                 max = roiMax; | ||||||
|  |             } | ||||||
|  |  | ||||||
|  |             if (min == 0) | ||||||
|  |             { | ||||||
|  |                 min = roiMin; | ||||||
|  |             } | ||||||
|  |  | ||||||
|  |             double mult = 235 / (zoom * (max - min)); | ||||||
|  |             double add = (0 - mult) * min * zoom + 10; | ||||||
|  |             HOperatorSet.ScaleImage(hImage, out HObject imageScaled, mult, add); | ||||||
|  |             HOperatorSet.ConvertImageType(imageScaled, out imageScaled, "byte"); | ||||||
|  |             Stopwatch sw = new Stopwatch(); | ||||||
|  |             sw.Start(); | ||||||
|  |  | ||||||
|  |             HOperatorSet.GetImagePointer1(imageScaled, out HTuple pointer, out HTuple type, out _, out _); | ||||||
|  |             Bitmap bitmap = new Bitmap(width, height, PixelFormat.Format24bppRgb); | ||||||
|  |             BitmapData bitmapData = bitmap.LockBits(new Rectangle(0, 0, width, height), ImageLockMode.ReadWrite, bitmap.PixelFormat); | ||||||
|  |  | ||||||
|  |             unsafe | ||||||
|  |             { | ||||||
|  |                 byte* data = (byte*)(IntPtr)pointer; | ||||||
|  |                 byte* bitmapDataBuff = (byte*)bitmapData.Scan0; | ||||||
|  |  | ||||||
|  |                 if (width % 4 != 0) | ||||||
|  |                 { | ||||||
|  |                     Parallel.For(0, height, h => | ||||||
|  |                     { | ||||||
|  |                         Parallel.For(0, width, w => | ||||||
|  |                         { | ||||||
|  |                             byte gray = data[h * width + w]; | ||||||
|  |                             byte[] convertBytes = ConvertByteToColorfulArray(gray); | ||||||
|  |  | ||||||
|  |                             Marshal.Copy(convertBytes, 0, (IntPtr)(bitmapDataBuff + h * bitmapData.Stride + w * 3), 3); | ||||||
|  |                         }); | ||||||
|  |                     }); | ||||||
|  |                 } | ||||||
|  |                 else | ||||||
|  |                 { | ||||||
|  |                     Parallel.For(0, width * height, i => | ||||||
|  |                     { | ||||||
|  |                         byte gray = data[i]; | ||||||
|  |                         byte[] convertBytes = ConvertByteToColorfulArray(gray); | ||||||
|  |  | ||||||
|  |                         Marshal.Copy(convertBytes, 0, (IntPtr)(bitmapDataBuff + i * 3), 3); | ||||||
|  |                     }); | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |             bitmap.UnlockBits(bitmapData); | ||||||
|  |  | ||||||
|  |             if (isShowHeightTip) | ||||||
|  |             { | ||||||
|  |                 List<byte> lableList = new List<byte>() { 5, 30, 60, 90, 120, 150, 180, 210, 240, 255 }; | ||||||
|  |                 Dictionary<double, Color> lableColorDict = lableList.ToDictionary( | ||||||
|  |                     u => (u - add) / (mult * zResolution), | ||||||
|  |                     u => | ||||||
|  |                     { | ||||||
|  |                         byte[] colorBytes = ConvertByteToColorfulArray(u); | ||||||
|  |                         return Color.FromArgb(colorBytes[2], colorBytes[1], colorBytes[0]); | ||||||
|  |                     }); | ||||||
|  |  | ||||||
|  |                 using (Graphics g = Graphics.FromImage(bitmap)) | ||||||
|  |                 { | ||||||
|  |                     int rectHeight = (int)(bitmap.Height / (5.0 * lableColorDict.Count)); | ||||||
|  |                     Font font = new Font("宋体", (int)(rectHeight * 0.75), GraphicsUnit.Pixel); | ||||||
|  |  | ||||||
|  |                     string lable = lableColorDict.ElementAt(0).Key.ToString("f3"); | ||||||
|  |                     SizeF lableSize = g.MeasureString(lable, font); | ||||||
|  |                     int rectWidth = (int)(lableSize.Width * 1.5); | ||||||
|  |  | ||||||
|  |                     int startX = 0; | ||||||
|  |                     int startY = 0; | ||||||
|  |                     foreach (KeyValuePair<double, Color> pair in lableColorDict) | ||||||
|  |                     { | ||||||
|  |                         g.FillRectangle(new SolidBrush(pair.Value), startX, startY, rectWidth, rectHeight); | ||||||
|  |                         g.DrawString(pair.Key.ToString("f3"), font, new SolidBrush(Color.White), (float)(startX + (rectWidth - lableSize.Width) / 2.0), (float)(startY + (rectHeight - lableSize.Height) / 2.0)); | ||||||
|  |  | ||||||
|  |                         startY += rectHeight; | ||||||
|  |                     } | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |  | ||||||
|  |             sw.Stop(); | ||||||
|  |             //LogAsync(DateTime.Now, EnumHelper.LogLevel.Information, $"转换耗时{sw.ElapsedMilliseconds}ms"); | ||||||
|  |             return bitmap; | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         private static byte[] ConvertByteToColorfulArray(byte gray) | ||||||
|  |         { | ||||||
|  |             byte[] bytes = new byte[3]; | ||||||
|  |             if (gray == 0) | ||||||
|  |             { | ||||||
|  |                 bytes[2] = 255; | ||||||
|  |                 bytes[1] = 255; | ||||||
|  |                 bytes[0] = 255; | ||||||
|  |             } | ||||||
|  |             if (gray > 0 && gray <= 63) | ||||||
|  |             { | ||||||
|  |                 bytes[2] = 0; | ||||||
|  |                 bytes[+1] = (byte)(254 - 4 * gray); | ||||||
|  |                 bytes[0] = 255; | ||||||
|  |             } | ||||||
|  |             if (gray >= 64 && gray <= 127) | ||||||
|  |             { | ||||||
|  |                 bytes[2] = 0; | ||||||
|  |                 bytes[1] = (byte)(4 * gray - 254); | ||||||
|  |                 bytes[0] = (byte)(510 - 4 * gray); | ||||||
|  |             } | ||||||
|  |             if (gray >= 128 && gray <= 191) | ||||||
|  |             { | ||||||
|  |                 bytes[2] = (byte)(4 * gray - 510); | ||||||
|  |                 bytes[1] = 255; | ||||||
|  |                 bytes[0] = 0; | ||||||
|  |             } | ||||||
|  |             if (gray >= 192 && gray <= 255) | ||||||
|  |             { | ||||||
|  |                 bytes[2] = 255; | ||||||
|  |                 bytes[1] = (byte)(1022 - 4 * gray); | ||||||
|  |                 bytes[0] = 0; | ||||||
|  |             } | ||||||
|  |  | ||||||
|  |             return bytes; | ||||||
|  |         } | ||||||
|  |         #endregion | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										724
									
								
								DH.Commons/Helper/OpenCVEngineTool.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										724
									
								
								DH.Commons/Helper/OpenCVEngineTool.cs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,724 @@ | |||||||
|  | using HalconDotNet; | ||||||
|  | using OpenCvSharp; | ||||||
|  | using OpenCvSharp.Extensions; | ||||||
|  | using System; | ||||||
|  | using System.Drawing; | ||||||
|  | using System.Drawing.Imaging; | ||||||
|  | using System.IO; | ||||||
|  | using System.Linq; | ||||||
|  | using System.Runtime.InteropServices; | ||||||
|  | using System.Threading.Tasks; | ||||||
|  |  | ||||||
|  | namespace XKRS.Common.Model | ||||||
|  | { | ||||||
|  |     public class OpenCVEngineTool : IDisposable | ||||||
|  |     { | ||||||
|  |         public void Dispose() | ||||||
|  |         { | ||||||
|  |             throw new NotImplementedException(); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |  | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |  | ||||||
|  |     public static class OpenCVHelper | ||||||
|  |     { | ||||||
|  |         [DllImport("kernel32.dll", EntryPoint = "RtlMoveMemory", SetLastError = false)] | ||||||
|  |         public static extern void CopyMemory(IntPtr dest, IntPtr src, uint count); | ||||||
|  |  | ||||||
|  |  | ||||||
|  |         public static byte[] MatToBytes(this Mat image) | ||||||
|  |         { | ||||||
|  |             if (image != null && image.Data != IntPtr.Zero) | ||||||
|  |             { | ||||||
|  |                 int size = (int)(image.Total() * image.ElemSize()); | ||||||
|  |                 byte[] bytes = new byte[size]; | ||||||
|  |                 Marshal.Copy(image.Data, bytes, 0, size); | ||||||
|  |                 return bytes; | ||||||
|  |             } | ||||||
|  |             else | ||||||
|  |             { | ||||||
|  |                 return null; | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         /// <summary> | ||||||
|  |         /// 获取水平拼接图片 | ||||||
|  |         /// </summary> | ||||||
|  |         /// <param name="map1"></param> | ||||||
|  |         /// <param name="map2"></param> | ||||||
|  |         /// <returns></returns> | ||||||
|  |         public static Bitmap GetHConcatImage(Bitmap map1, Bitmap map2) | ||||||
|  |         { | ||||||
|  |             var mat1 = map1.ToMat(); | ||||||
|  |             var mat2 = map2.ToMat(); | ||||||
|  |             //var maxChannel = Math.Max(mat1.Channels(), mat2.Channels()); | ||||||
|  |             //var maxType = Math.Max(mat1.Type(), mat2.Type()); | ||||||
|  |  | ||||||
|  |             //转通道数 | ||||||
|  |             mat1 = mat1.CvtColor(ColorConversionCodes.GRAY2BGRA); | ||||||
|  |             //转位深 | ||||||
|  |             mat1.ConvertTo(mat1, mat2.Type()); | ||||||
|  |             Mat resMat = new Mat(mat1.Height, mat1.Width, mat2.Type(), new Scalar(0)); | ||||||
|  |             Cv2.HConcat(mat1, mat2, resMat); | ||||||
|  |             mat1.Dispose(); | ||||||
|  |             mat2.Dispose(); | ||||||
|  |             return resMat.ToBitmap(); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         public static Mat To3Channels(this Mat img) | ||||||
|  |         { | ||||||
|  |             if (img == null) | ||||||
|  |                 return null; | ||||||
|  |             Mat resMat = new Mat(img.Rows, img.Cols, MatType.CV_8UC3); | ||||||
|  |             Mat[] channels = new Mat[3]; ; | ||||||
|  |             for (int i = 0; i < 3; i++) | ||||||
|  |             { | ||||||
|  |                 channels[i] = img; | ||||||
|  |             } | ||||||
|  |             Cv2.Merge(channels, resMat); | ||||||
|  |             img.Dispose(); | ||||||
|  |             img = null; | ||||||
|  |             return resMat; | ||||||
|  |         } | ||||||
|  |         /// <summary> | ||||||
|  |         /// 把OpenCV图像转换到Halcon图像 | ||||||
|  |         /// </summary> | ||||||
|  |         /// <param name="mImage">OpenCV图像_Mat</param> | ||||||
|  |         /// <returns>Halcon图像_HObject</returns> | ||||||
|  |         public static HObject MatToHImage(Mat mImage) | ||||||
|  |         { | ||||||
|  |             try | ||||||
|  |             { | ||||||
|  |                 HObject hImage; | ||||||
|  |                 int matChannels = 0;   // 通道数 | ||||||
|  |                 Type matType = null; | ||||||
|  |                 uint width, height;   // 宽,高 | ||||||
|  |                 width = height = 0;  // 宽,高初始化 | ||||||
|  |  | ||||||
|  |                 // 获取通道数 | ||||||
|  |                 matChannels = mImage.Channels(); | ||||||
|  |                 if (matChannels == 0) | ||||||
|  |                 { | ||||||
|  |                     return null; | ||||||
|  |                 } | ||||||
|  |                 if (matChannels == 1)        // 单通道 | ||||||
|  |                 //if (true)        // 单通道 | ||||||
|  |                 { | ||||||
|  |                     IntPtr ptr;      // 灰度图通道 | ||||||
|  |                     Mat[] mats = mImage.Split(); | ||||||
|  |  | ||||||
|  |                     // 改自:Mat.GetImagePointer1(mImage, out ptr, out matType, out width, out height);    // ptr=2157902018096    cType=byte    width=830    height=822 | ||||||
|  |                     ptr = mats[0].Data;          // 取灰度图值 | ||||||
|  |                     matType = mImage.GetType();  // byte | ||||||
|  |                     height = (uint)mImage.Rows;        // 高 | ||||||
|  |                     width = (uint)mImage.Cols;         // 宽 | ||||||
|  |  | ||||||
|  |                     // 改自:hImage = new HObject(new OpenCvSharp.Size(width, height), MatType.CV_8UC1, newScalar(0)); | ||||||
|  |                     byte[] dataGrayScaleImage = new byte[width * height];      //Mat dataGrayScaleImage = new Mat(new OpenCvSharp.Size(width, height), MatType.CV_8UC1); | ||||||
|  |  | ||||||
|  |                     unsafe | ||||||
|  |                     { | ||||||
|  |                         fixed (byte* ptrdata = dataGrayScaleImage) | ||||||
|  |                         { | ||||||
|  |  | ||||||
|  |                             #region 按行复制 | ||||||
|  |                             //for (int i = 0; i < height; i++) | ||||||
|  |                             //{ | ||||||
|  |                             //    CopyMemory((IntPtr)(ptrdata + width * i), new IntPtr((long)ptr + width *i), width); | ||||||
|  |                             //} | ||||||
|  |  | ||||||
|  |                             #endregion | ||||||
|  |  | ||||||
|  |                             CopyMemory((IntPtr)ptrdata, new IntPtr((long)ptr), width * height); | ||||||
|  |                             HOperatorSet.GenImage1(out hImage, "byte", width, height, (IntPtr)ptrdata); | ||||||
|  |  | ||||||
|  |                         } | ||||||
|  |                     } | ||||||
|  |                     return hImage; | ||||||
|  |                 } | ||||||
|  |                 else if (matChannels == 3)   // 三通道 | ||||||
|  |                 { | ||||||
|  |                     IntPtr ptrRed;    // R通道图 | ||||||
|  |                     IntPtr ptrGreen;  // G通道图 | ||||||
|  |                     IntPtr ptrBlue;   // B通道图 | ||||||
|  |                     Mat[] mats = mImage.Split(); | ||||||
|  |  | ||||||
|  |                     ptrRed = mats[0].Data;    // 取R通道值 | ||||||
|  |                     ptrGreen = mats[1].Data;  // 取G通道值 | ||||||
|  |                     ptrBlue = mats[2].Data;   // 取B通道值 | ||||||
|  |                     matType = mImage.GetType();  // 类型 | ||||||
|  |                     height = (uint)mImage.Rows;        // 高 | ||||||
|  |                     width = (uint)mImage.Cols;         // 宽 | ||||||
|  |  | ||||||
|  |                     // 改自:hImage = new HObject(new OpenCvSharp.Size(width, height), MatType.CV_8UC1, new Scalar(0)); | ||||||
|  |                     byte[] dataRed = new byte[width * height];      //Mat dataGrayScaleImage = new Mat(new OpenCvSharp.Size(width, height), MatType.CV_8UC1); | ||||||
|  |                     byte[] dataGreen = new byte[width * height]; | ||||||
|  |                     byte[] dataBlue = new byte[width * height]; | ||||||
|  |  | ||||||
|  |                     unsafe | ||||||
|  |                     { | ||||||
|  |                         fixed (byte* ptrdataRed = dataRed, ptrdataGreen = dataGreen, ptrdataBlue = dataBlue) | ||||||
|  |                         { | ||||||
|  |  | ||||||
|  |                             #region 按行复制 | ||||||
|  |                             //HImage himg = new HImage("byte", width, height, (IntPtr)ptrdataRed); | ||||||
|  |                             //for (int i = 0; i < height; i++) | ||||||
|  |                             //{ | ||||||
|  |                             //     CopyMemory((IntPtr)(ptrdataRed + width * i), new IntPtr((long)ptrRed +width * i), width); | ||||||
|  |                             //     CopyMemory((IntPtr)(ptrdataGreen + width * i), new IntPtr((long)ptrGreen+ width * i), width); | ||||||
|  |                             //     CopyMemory((IntPtr)(ptrdataBlue + width * i), new IntPtr((long)ptrBlue +width * i), width); | ||||||
|  |                             //} | ||||||
|  |  | ||||||
|  |                             #endregion | ||||||
|  |  | ||||||
|  |                             CopyMemory((IntPtr)ptrdataRed, new IntPtr((long)ptrRed), width* height);        // 复制R通道 | ||||||
|  |                             CopyMemory((IntPtr)ptrdataGreen, new IntPtr((long)ptrGreen), width * height);    // 复制G通道 | ||||||
|  |                             CopyMemory((IntPtr)ptrdataBlue, new IntPtr((long)ptrBlue), width * height);      // 复制B通道 | ||||||
|  |                             HOperatorSet.GenImage3(out hImage, "byte", width, height, (IntPtr)ptrdataRed, (IntPtr)ptrdataGreen, (IntPtr)ptrdataBlue);   // 合成 | ||||||
|  |                         } | ||||||
|  |                     } | ||||||
|  |                     return hImage; | ||||||
|  |                 } | ||||||
|  |                 else | ||||||
|  |                 { | ||||||
|  |                     return null; | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |             catch (Exception ex) | ||||||
|  |             { | ||||||
|  |                 throw ex; | ||||||
|  |             } | ||||||
|  |  | ||||||
|  |         } | ||||||
|  |   | ||||||
|  |   | ||||||
|  |   | ||||||
|  |  | ||||||
|  |  | ||||||
|  |         public static Mat HImageToMat(this HObject hobj) | ||||||
|  |         { | ||||||
|  |             try | ||||||
|  |             { | ||||||
|  |                 Mat mImage; | ||||||
|  |                 HTuple htChannels; | ||||||
|  |                 HTuple cType = null; | ||||||
|  |                 HTuple width, height; | ||||||
|  |                 width = height = 0; | ||||||
|  |  | ||||||
|  |                 HOperatorSet.CountChannels(hobj, out htChannels); | ||||||
|  |  | ||||||
|  |                 if (htChannels.Length == 0) | ||||||
|  |                 { | ||||||
|  |                     return null; | ||||||
|  |                 } | ||||||
|  |                 if (htChannels[0].I == 1) | ||||||
|  |                 { | ||||||
|  |                     HTuple ptr; | ||||||
|  |                     HOperatorSet.GetImagePointer1(hobj, out ptr, out cType, out width, out height); | ||||||
|  |                     mImage = new Mat(height, width, MatType.CV_8UC1, new Scalar(0)); | ||||||
|  |  | ||||||
|  |                     unsafe | ||||||
|  |                     { | ||||||
|  |                         CopyMemory(mImage.Data, new IntPtr((byte*)ptr.IP), (uint)(width * height));// CopyMemory(要复制到的地址,复制源的地址,复制的长度) | ||||||
|  |                     } | ||||||
|  |  | ||||||
|  |                     return mImage; | ||||||
|  |                 } | ||||||
|  |                 else if (htChannels[0].I == 3) | ||||||
|  |                 { | ||||||
|  |                     HTuple ptrRed; | ||||||
|  |                     HTuple ptrGreen; | ||||||
|  |                     HTuple ptrBlue; | ||||||
|  |  | ||||||
|  |                     HOperatorSet.GetImagePointer3(hobj, out ptrRed, out ptrGreen, out ptrBlue, out cType, out width, out height); | ||||||
|  |                     Mat pImageRed = new Mat(new OpenCvSharp.Size(width, height), MatType.CV_8UC1); | ||||||
|  |                     Mat pImageGreen = new Mat(new OpenCvSharp.Size(width, height), MatType.CV_8UC1); | ||||||
|  |                     Mat pImageBlue = new Mat(new OpenCvSharp.Size(width, height), MatType.CV_8UC1); | ||||||
|  |                     mImage = new Mat(new OpenCvSharp.Size(width, height), MatType.CV_8UC3, new Scalar(0, 0, 0)); | ||||||
|  |                     unsafe | ||||||
|  |                     { | ||||||
|  |                         CopyMemory(pImageRed.Data, new IntPtr((byte*)ptrRed.IP), (uint)(width * height));        // CopyMemory(要复制到的地址,复制源的地址,复制的长度)_Red | ||||||
|  |                         CopyMemory(pImageGreen.Data, new IntPtr((byte*)ptrGreen.IP), (uint)(width * height));  // CopyMemory(要复制到的地址,复制源的地址,复制的长度)_Green | ||||||
|  |                         CopyMemory(pImageBlue.Data, new IntPtr((byte*)ptrBlue.IP), (uint)(width * height));    // CopyMemory(要复制到的地址,复制源的地址,复制的长度)_Blue | ||||||
|  |  | ||||||
|  |                     } | ||||||
|  |                     Mat[] multi = new Mat[] { pImageBlue, pImageGreen, pImageRed }; | ||||||
|  |                     Cv2.Merge(multi, mImage); | ||||||
|  |                     pImageRed.Dispose(); | ||||||
|  |                     pImageRed = null; | ||||||
|  |                     pImageGreen.Dispose(); | ||||||
|  |                     pImageGreen = null; | ||||||
|  |                     pImageBlue.Dispose(); | ||||||
|  |                     pImageBlue = null; | ||||||
|  |                     return mImage; | ||||||
|  |                 } | ||||||
|  |                 else | ||||||
|  |                 { | ||||||
|  |                     return null; | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |             catch (Exception ex) | ||||||
|  |             { | ||||||
|  |                 throw ex; | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         ///   <summary> | ||||||
|  |         ///  从内存流中指定位置,读取数据 | ||||||
|  |         ///   </summary> | ||||||
|  |         ///   <param name="curStream"></param> | ||||||
|  |         ///   <param name="startPosition"></param> | ||||||
|  |         ///   <param name="length"></param> | ||||||
|  |         ///   <returns></returns> | ||||||
|  |         public static int ReadData(MemoryStream curStream, int startPosition, int length) | ||||||
|  |         { | ||||||
|  |             int result = -1; | ||||||
|  |  | ||||||
|  |             byte[] tempData = new byte[length]; | ||||||
|  |             curStream.Position = startPosition; | ||||||
|  |             curStream.Read(tempData, 0, length); | ||||||
|  |             result = BitConverter.ToInt32(tempData, 0); | ||||||
|  |  | ||||||
|  |             return result; | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         ///   <summary> | ||||||
|  |         ///  使用byte[]数据,生成三通道 BMP 位图 | ||||||
|  |         ///   </summary> | ||||||
|  |         ///   <param name="originalImageData"></param> | ||||||
|  |         ///   <param name="originalWidth"></param> | ||||||
|  |         ///   <param name="originalHeight"></param> | ||||||
|  |         ///   <returns></returns> | ||||||
|  |         public static Bitmap CreateColorBitmap(byte[] originalImageData, int originalWidth, int originalHeight, byte[] color_map) | ||||||
|  |         { | ||||||
|  |             // 指定8位格式,即256色 | ||||||
|  |             Bitmap resultBitmap = new Bitmap(originalWidth, originalHeight, System.Drawing.Imaging.PixelFormat.Format8bppIndexed); | ||||||
|  |  | ||||||
|  |             // 将该位图存入内存中 | ||||||
|  |             MemoryStream curImageStream = new MemoryStream(); | ||||||
|  |             resultBitmap.Save(curImageStream, System.Drawing.Imaging.ImageFormat.Bmp); | ||||||
|  |             curImageStream.Flush(); | ||||||
|  |  | ||||||
|  |             // 由于位图数据需要DWORD对齐(4byte倍数),计算需要补位的个数 | ||||||
|  |             int curPadNum = ((originalWidth * 8 + 31) / 32 * 4) - originalWidth; | ||||||
|  |  | ||||||
|  |             // 最终生成的位图数据大小 | ||||||
|  |             int bitmapDataSize = ((originalWidth * 8 + 31) / 32 * 4) * originalHeight; | ||||||
|  |  | ||||||
|  |             // 数据部分相对文件开始偏移,具体可以参考位图文件格式 | ||||||
|  |             int dataOffset = ReadData(curImageStream, 10, 4); | ||||||
|  |  | ||||||
|  |  | ||||||
|  |             // 改变调色板,因为默认的调色板是32位彩色的,需要修改为256色的调色板 | ||||||
|  |             int paletteStart = 54; | ||||||
|  |             int paletteEnd = dataOffset; | ||||||
|  |             int color = 0; | ||||||
|  |  | ||||||
|  |             for (int i = paletteStart; i < paletteEnd; i += 4) | ||||||
|  |             { | ||||||
|  |                 byte[] tempColor = new byte[4]; | ||||||
|  |                 tempColor[0] = (byte)color; | ||||||
|  |                 tempColor[1] = (byte)color; | ||||||
|  |                 tempColor[2] = (byte)color; | ||||||
|  |                 tempColor[3] = (byte)0; | ||||||
|  |                 color++; | ||||||
|  |  | ||||||
|  |                 curImageStream.Position = i; | ||||||
|  |                 curImageStream.Write(tempColor, 0, 4); | ||||||
|  |             } | ||||||
|  |  | ||||||
|  |             // 最终生成的位图数据,以及大小,高度没有变,宽度需要调整 | ||||||
|  |             byte[] destImageData = new byte[bitmapDataSize]; | ||||||
|  |             int destWidth = originalWidth + curPadNum; | ||||||
|  |  | ||||||
|  |             // 生成最终的位图数据,注意的是,位图数据 从左到右,从下到上,所以需要颠倒 | ||||||
|  |             for (int originalRowIndex = originalHeight - 1; originalRowIndex >= 0; originalRowIndex--) | ||||||
|  |             { | ||||||
|  |                 int destRowIndex = originalHeight - originalRowIndex - 1; | ||||||
|  |  | ||||||
|  |                 for (int dataIndex = 0; dataIndex < originalWidth; dataIndex++) | ||||||
|  |                 { | ||||||
|  |                     // 同时还要注意,新的位图数据的宽度已经变化destWidth,否则会产生错位 | ||||||
|  |                     destImageData[destRowIndex * destWidth + dataIndex] = originalImageData[originalRowIndex * originalWidth + dataIndex]; | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |  | ||||||
|  |             // 将流的Position移到数据段    | ||||||
|  |             curImageStream.Position = dataOffset; | ||||||
|  |  | ||||||
|  |             // 将新位图数据写入内存中 | ||||||
|  |             curImageStream.Write(destImageData, 0, bitmapDataSize); | ||||||
|  |  | ||||||
|  |             curImageStream.Flush(); | ||||||
|  |  | ||||||
|  |             // 将内存中的位图写入Bitmap对象 | ||||||
|  |             resultBitmap = new Bitmap(curImageStream); | ||||||
|  |  | ||||||
|  |             resultBitmap = Convert8to24(resultBitmap, color_map);  // 转为3通道图像 | ||||||
|  |  | ||||||
|  |             return resultBitmap; | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         // 实现单通道到多通道 | ||||||
|  |         public static Bitmap Convert8to24(this Bitmap bmp, byte[] color_map) | ||||||
|  |         { | ||||||
|  |  | ||||||
|  |             Rectangle rect = new System.Drawing.Rectangle(0, 0, bmp.Width, bmp.Height); | ||||||
|  |             BitmapData bitmapData = bmp.LockBits(rect, ImageLockMode.ReadOnly, bmp.PixelFormat); | ||||||
|  |  | ||||||
|  |             //计算实际8位图容量 | ||||||
|  |             int size8 = bitmapData.Stride * bmp.Height; | ||||||
|  |             byte[] grayValues = new byte[size8]; | ||||||
|  |  | ||||||
|  |             //// 申请目标位图的变量,并将其内存区域锁定   | ||||||
|  |             Bitmap TempBmp = new Bitmap(bmp.Width, bmp.Height, PixelFormat.Format24bppRgb); | ||||||
|  |             BitmapData TempBmpData = TempBmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height), ImageLockMode.WriteOnly, PixelFormat.Format24bppRgb); | ||||||
|  |  | ||||||
|  |  | ||||||
|  |             //// 获取图像参数以及设置24位图信息  | ||||||
|  |             int stride = TempBmpData.Stride;  // 扫描线的宽度   | ||||||
|  |             int offset = stride - TempBmp.Width;  // 显示宽度与扫描线宽度的间隙   | ||||||
|  |             IntPtr iptr = TempBmpData.Scan0;  // 获取bmpData的内存起始位置   | ||||||
|  |             int scanBytes = stride * TempBmp.Height;// 用stride宽度,表示这是内存区域的大小   | ||||||
|  |  | ||||||
|  |             // 下面把原始的显示大小字节数组转换为内存中实际存放的字节数组   | ||||||
|  |             byte[] pixelValues = new byte[scanBytes];  //为目标数组分配内存   | ||||||
|  |             System.Runtime.InteropServices.Marshal.Copy(bitmapData.Scan0, grayValues, 0, size8); | ||||||
|  |  | ||||||
|  |             for (int i = 0; i < bmp.Height; i++) | ||||||
|  |             { | ||||||
|  |  | ||||||
|  |                 for (int j = 0; j < bitmapData.Stride; j++) | ||||||
|  |                 { | ||||||
|  |  | ||||||
|  |                     if (j >= bmp.Width) | ||||||
|  |                         continue; | ||||||
|  |  | ||||||
|  |                     int indexSrc = i * bitmapData.Stride + j; | ||||||
|  |                     int realIndex = i * TempBmpData.Stride + j * 3; | ||||||
|  |  | ||||||
|  |                     // color_id:就是预测出来的结果 | ||||||
|  |                     int color_id = (int)grayValues[indexSrc] % 256; | ||||||
|  |  | ||||||
|  |                     if (color_id == 0) // 分割中类别1对应值1,而背景往往为0,因此这里就将背景置为[0, 0, 0] | ||||||
|  |                     { | ||||||
|  |                         // 空白 | ||||||
|  |                         pixelValues[realIndex] = 0; | ||||||
|  |                         pixelValues[realIndex + 1] = 0; | ||||||
|  |                         pixelValues[realIndex + 2] = 0; | ||||||
|  |                     } | ||||||
|  |                     else | ||||||
|  |                     { | ||||||
|  |                         // 替换为color_map中的颜色值 | ||||||
|  |                         pixelValues[realIndex] = color_map[color_id * 3]; | ||||||
|  |                         pixelValues[realIndex + 1] = color_map[color_id * 3 + 1]; | ||||||
|  |                         pixelValues[realIndex + 2] = color_map[color_id * 3 + 2]; | ||||||
|  |                     } | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |  | ||||||
|  |             //Parallel.For(0, width * height, i => | ||||||
|  |             //     { | ||||||
|  |             //         int index = (i + 1) % width + widthIn4 * ((i + 1) / width) - 1; | ||||||
|  |  | ||||||
|  |             //         showBitmapBuffer[index * 6] = bitmapBuffer[index * 6] = data[i * 2]; | ||||||
|  |             //         showBitmapBuffer[index * 6 + 1] = bitmapBuffer[index * 6 + 1] = data[i * 2 + 1]; | ||||||
|  |             //     }); | ||||||
|  |  | ||||||
|  |             // 用Marshal的Copy方法,将刚才得到的内存字节数组复制到BitmapData中   | ||||||
|  |             Marshal.Copy(pixelValues, 0, iptr, scanBytes); | ||||||
|  |             TempBmp.UnlockBits(TempBmpData);  // 解锁内存区域   | ||||||
|  |             bmp.UnlockBits(bitmapData); | ||||||
|  |             return TempBmp; | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |  | ||||||
|  |         // 获取伪彩色图的RGB值 -- 同时也是适用于检测框分类颜色 | ||||||
|  |         public static byte[] GetColorMap(int num_classes = 256) | ||||||
|  |         { | ||||||
|  |             num_classes += 1; | ||||||
|  |             byte[] color_map = new byte[num_classes * 3]; | ||||||
|  |             for (int i = 0; i < num_classes; i++) | ||||||
|  |             { | ||||||
|  |                 int j = 0; | ||||||
|  |                 int lab = i; | ||||||
|  |                 while (lab != 0) | ||||||
|  |                 { | ||||||
|  |                     color_map[i * 3] |= (byte)(((lab >> 0) & 1) << (7 - j)); | ||||||
|  |                     color_map[i * 3 + 1] |= (byte)(((lab >> 1) & 1) << (7 - j)); | ||||||
|  |                     color_map[i * 3 + 2] |= (byte)(((lab >> 2) & 1) << (7 - j)); | ||||||
|  |  | ||||||
|  |                     j += 1; | ||||||
|  |                     lab >>= 3; | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |  | ||||||
|  |             // 去掉底色 | ||||||
|  |             color_map = color_map.Skip(3).ToArray(); | ||||||
|  |             return color_map; | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         // GetGrayMap | ||||||
|  |         public static byte[] GetGrayMap(int num_classes = 256) | ||||||
|  |         { | ||||||
|  |             byte[] color_map = new byte[num_classes]; | ||||||
|  |             for (int i = 0; i < num_classes; i++) | ||||||
|  |             { | ||||||
|  |                 if (i <= 100) | ||||||
|  |                     color_map[i] = 0; | ||||||
|  |                 if (i > 100 && i <= 200) | ||||||
|  |                     color_map[i] = 100; | ||||||
|  |                 if (i > 200) | ||||||
|  |                     color_map[i] = 255; | ||||||
|  |  | ||||||
|  |             } | ||||||
|  |             return color_map; | ||||||
|  |         } | ||||||
|  |         /// <summary> | ||||||
|  |         /// 像素点阵转换为bitmap 二值化图 | ||||||
|  |         /// </summary> | ||||||
|  |         /// <param name="rawValues">byte[]数组</param> | ||||||
|  |         /// <param name="width">图片的宽度</param> | ||||||
|  |         /// <param name="height">图片的高度</param> | ||||||
|  |         /// <returns>bitmap图片</returns> | ||||||
|  |         public static Bitmap CreateBinaryBitmap(byte[] rawValues, int width, int height) | ||||||
|  |         { | ||||||
|  |             Bitmap bmp = new Bitmap(width, height, System.Drawing.Imaging.PixelFormat.Format8bppIndexed); | ||||||
|  |             BitmapData bmpData = bmp.LockBits(new System.Drawing.Rectangle(0, 0, width, height), ImageLockMode.WriteOnly, System.Drawing.Imaging.PixelFormat.Format8bppIndexed); | ||||||
|  |             //获取图像参数 | ||||||
|  |             int stride = bmpData.Stride;  // 扫描线的宽度   | ||||||
|  |             int offset = stride - width;  // 显示宽度与扫描线宽度的间隙   | ||||||
|  |             IntPtr iptr = bmpData.Scan0;  // 获取bmpData的内存起始位置   | ||||||
|  |             int scanBytes = stride * height;// 用stride宽度,表示这是内存区域的大小   | ||||||
|  |                                             //下面把原始的显示大小字节数组转换为内存中实际存放的字节数组 | ||||||
|  |             int posScan = 0, posReal = 0;// 分别设置两个位置指针,指向源数组和目标数组   | ||||||
|  |             byte[] pixelValues = new byte[scanBytes];  //为目标数组分配内存   | ||||||
|  |             for (int x = 0; x < height; x++) | ||||||
|  |             { | ||||||
|  |                 //下面的循环节是模拟行扫描 | ||||||
|  |                 for (int y = 0; y < width; y++) | ||||||
|  |                 { | ||||||
|  |                     pixelValues[posScan++] = rawValues[posReal++] == 0 ? (byte)0 : (byte)255; | ||||||
|  |                 } | ||||||
|  |                 posScan += offset;  //行扫描结束,要将目标位置指针移过那段“间隙”   | ||||||
|  |             } | ||||||
|  |             //用Marshal的Copy方法,将刚才得到的内存字节数组复制到BitmapData中 | ||||||
|  |             Marshal.Copy(pixelValues, 0, iptr, scanBytes); | ||||||
|  |             bmp.UnlockBits(bmpData);  // 解锁内存区域   | ||||||
|  |                                       //下面的代码是为了修改生成位图的索引表,从伪彩修改为灰度 | ||||||
|  |             ColorPalette tempPalette; | ||||||
|  |             using (Bitmap tempBmp = new Bitmap(1, 1, System.Drawing.Imaging.PixelFormat.Format8bppIndexed)) | ||||||
|  |             { | ||||||
|  |                 tempPalette = tempBmp.Palette; | ||||||
|  |             } | ||||||
|  |             for (int i = 0; i < 256; i++) | ||||||
|  |             { | ||||||
|  |                 tempPalette.Entries[i] = System.Drawing.Color.FromArgb(i, i, i); | ||||||
|  |             } | ||||||
|  |  | ||||||
|  |             bmp.Palette = tempPalette; | ||||||
|  |  | ||||||
|  |             return bmp; | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         /// <summary> | ||||||
|  |         /// 像素点阵转换为bitmap灰度图 | ||||||
|  |         /// </summary> | ||||||
|  |         /// <param name="rawValues">byte[]数组</param> | ||||||
|  |         /// <param name="width">图片的宽度</param> | ||||||
|  |         /// <param name="height">图片的高度</param> | ||||||
|  |         /// <returns>bitmap图片</returns> | ||||||
|  |         public static Bitmap CreateGrayBitmap(byte[] rawValues, int width, int height) | ||||||
|  |         { | ||||||
|  |             Bitmap bmp = new Bitmap(width, height, System.Drawing.Imaging.PixelFormat.Format8bppIndexed); | ||||||
|  |             BitmapData bmpData = bmp.LockBits(new System.Drawing.Rectangle(0, 0, width, height), ImageLockMode.WriteOnly, System.Drawing.Imaging.PixelFormat.Format8bppIndexed); | ||||||
|  |             //获取图像参数 | ||||||
|  |             int stride = bmpData.Stride;  // 扫描线的宽度   | ||||||
|  |             int offset = stride - width;  // 显示宽度与扫描线宽度的间隙   | ||||||
|  |             IntPtr iptr = bmpData.Scan0;  // 获取bmpData的内存起始位置   | ||||||
|  |             int scanBytes = stride * height;// 用stride宽度,表示这是内存区域的大小   | ||||||
|  |                                             //下面把原始的显示大小字节数组转换为内存中实际存放的字节数组 | ||||||
|  |             int posScan = 0, posReal = 0;// 分别设置两个位置指针,指向源数组和目标数组   | ||||||
|  |             byte[] pixelValues = new byte[scanBytes];  //为目标数组分配内存   | ||||||
|  |             for (int x = 0; x < height; x++) | ||||||
|  |             { | ||||||
|  |                 //下面的循环节是模拟行扫描 | ||||||
|  |                 for (int y = 0; y < width; y++) | ||||||
|  |                 { | ||||||
|  |                     pixelValues[posScan++] = rawValues[posReal++]; | ||||||
|  |                 } | ||||||
|  |                 posScan += offset;  //行扫描结束,要将目标位置指针移过那段“间隙”   | ||||||
|  |             } | ||||||
|  |             //用Marshal的Copy方法,将刚才得到的内存字节数组复制到BitmapData中 | ||||||
|  |             Marshal.Copy(pixelValues, 0, iptr, scanBytes); | ||||||
|  |             bmp.UnlockBits(bmpData);  // 解锁内存区域   | ||||||
|  |                                       //下面的代码是为了修改生成位图的索引表,从伪彩修改为灰度 | ||||||
|  |             ColorPalette tempPalette; | ||||||
|  |             using (Bitmap tempBmp = new Bitmap(1, 1, System.Drawing.Imaging.PixelFormat.Format8bppIndexed)) | ||||||
|  |             { | ||||||
|  |                 tempPalette = tempBmp.Palette; | ||||||
|  |             } | ||||||
|  |             for (int i = 0; i < 256; i++) | ||||||
|  |             { | ||||||
|  |                 tempPalette.Entries[i] = System.Drawing.Color.FromArgb(i, i, i); | ||||||
|  |             } | ||||||
|  |  | ||||||
|  |             bmp.Palette = tempPalette; | ||||||
|  |  | ||||||
|  |             return bmp; | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |  | ||||||
|  |         //分别基于像素(GetPixel和SetPixel)、基于内存、基于指针这三种方法增强图片对比度。 | ||||||
|  |         // 第一种方法:像素提取法。速度慢 基于像素:400-600ms | ||||||
|  |         public static Bitmap MethodBaseOnPixel(Bitmap bitmap, int degree) | ||||||
|  |         { | ||||||
|  |             Color curColor; | ||||||
|  |             int grayR, grayG, grayB; | ||||||
|  |  | ||||||
|  |             double Deg = (100.0 + degree) / 100.0; | ||||||
|  |             for (int i = 0; i < bitmap.Width; i++) | ||||||
|  |             { | ||||||
|  |                 for (int j = 0; j < bitmap.Height; j++) | ||||||
|  |                 { | ||||||
|  |                     curColor = bitmap.GetPixel(i, j); | ||||||
|  |                     grayR = Convert.ToInt32((((curColor.R / 255.0 - 0.5) * Deg + 0.5)) * 255); | ||||||
|  |                     grayG = Convert.ToInt32((((curColor.G / 255.0 - 0.5) * Deg + 0.5)) * 255); | ||||||
|  |                     grayB = Convert.ToInt32((((curColor.B / 255.0 - 0.5) * Deg + 0.5)) * 255); | ||||||
|  |                     if (grayR < 0) | ||||||
|  |                         grayR = 0; | ||||||
|  |                     else if (grayR > 255) | ||||||
|  |                         grayR = 255; | ||||||
|  |  | ||||||
|  |                     if (grayB < 0) | ||||||
|  |                         grayB = 0; | ||||||
|  |                     else if (grayB > 255) | ||||||
|  |                         grayB = 255; | ||||||
|  |  | ||||||
|  |                     if (grayG < 0) | ||||||
|  |                         grayG = 0; | ||||||
|  |                     else if (grayG > 255) | ||||||
|  |                         grayG = 255; | ||||||
|  |  | ||||||
|  |                     bitmap.SetPixel(i, j, Color.FromArgb(grayR, grayG, grayB)); | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |  | ||||||
|  |             return bitmap; | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         // 第二种方法:基于内存 17-18ms | ||||||
|  |         public static unsafe Bitmap MethodBaseOnMemory(Bitmap bitmap, int degree) | ||||||
|  |         { | ||||||
|  |             if (bitmap == null) | ||||||
|  |             { | ||||||
|  |                 return null; | ||||||
|  |             } | ||||||
|  |             double Deg = (100.0 + degree) / 100.0; | ||||||
|  |  | ||||||
|  |             int width = bitmap.Width; | ||||||
|  |             int height = bitmap.Height; | ||||||
|  |  | ||||||
|  |             int length = height * 3 * width; | ||||||
|  |             byte[] RGB = new byte[length]; | ||||||
|  |  | ||||||
|  |             BitmapData data = bitmap.LockBits(new Rectangle(0, 0, width, height), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb); | ||||||
|  |  | ||||||
|  |             System.IntPtr Scan0 = data.Scan0; | ||||||
|  |             System.Runtime.InteropServices.Marshal.Copy(Scan0, RGB, 0, length); | ||||||
|  |  | ||||||
|  |             double gray = 0; | ||||||
|  |             for (int i = 0; i < RGB.Length; i += 3) | ||||||
|  |             { | ||||||
|  |                 for (int j = 0; j < 3; j++) | ||||||
|  |                 { | ||||||
|  |                     gray = (((RGB[i + j] / 255.0 - 0.5) * Deg + 0.5)) * 255.0; | ||||||
|  |                     if (gray > 255) | ||||||
|  |                         gray = 255; | ||||||
|  |  | ||||||
|  |                     if (gray < 0) | ||||||
|  |                         gray = 0; | ||||||
|  |                     RGB[i + j] = (byte)gray; | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |  | ||||||
|  |             System.Runtime.InteropServices.Marshal.Copy(RGB, 0, Scan0, length);// 此处Copy是之前Copy的逆操作 | ||||||
|  |             bitmap.UnlockBits(data); | ||||||
|  |             return bitmap; | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         //第三种方法:基于指针 20-23ms | ||||||
|  |         public static unsafe Bitmap MethodBaseOnPtr(Bitmap b, int degree) | ||||||
|  |         { | ||||||
|  |             if (b == null) | ||||||
|  |             { | ||||||
|  |                 return null; | ||||||
|  |             } | ||||||
|  |             try | ||||||
|  |             { | ||||||
|  |                 double num = 0.0; | ||||||
|  |                 double num2 = (100.0 + degree) / 100.0; | ||||||
|  |                 num2 *= num2; | ||||||
|  |                 int width = b.Width; | ||||||
|  |                 int height = b.Height; | ||||||
|  |                 BitmapData bitmapdata = b.LockBits(new Rectangle(0, 0, width, height), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb); | ||||||
|  |                 byte* numPtr = (byte*)bitmapdata.Scan0; | ||||||
|  |  | ||||||
|  |                 int offset = bitmapdata.Stride - (width * 3); | ||||||
|  |                 for (int i = 0; i < height; i++) | ||||||
|  |                 { | ||||||
|  |                     for (int j = 0; j < width; j++) | ||||||
|  |                     { | ||||||
|  |                         for (int k = 0; k < 3; k++) | ||||||
|  |                         { | ||||||
|  |                             num = ((((((double)numPtr[k]) / 255.0) - 0.5) * num2) + 0.5) * 255.0; | ||||||
|  |                             if (num < 0.0) | ||||||
|  |                             { | ||||||
|  |                                 num = 0.0; | ||||||
|  |                             } | ||||||
|  |                             if (num > 255.0) | ||||||
|  |                             { | ||||||
|  |                                 num = 255.0; | ||||||
|  |                             } | ||||||
|  |                             numPtr[k] = (byte)num; | ||||||
|  |                         } | ||||||
|  |                         numPtr += 3; | ||||||
|  |  | ||||||
|  |                     } | ||||||
|  |                     numPtr += offset; | ||||||
|  |                 } | ||||||
|  |                 b.UnlockBits(bitmapdata); | ||||||
|  |                 return b; | ||||||
|  |             } | ||||||
|  |             catch | ||||||
|  |             { | ||||||
|  |                 return b; | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         public static double GetRoiArae(Mat src, Rect rect) | ||||||
|  |         { | ||||||
|  |             //初始面积为0 | ||||||
|  |             double Area = 0; | ||||||
|  |             //获取感兴趣区域 | ||||||
|  |             src = src[rect]; | ||||||
|  |             //转为单通道 | ||||||
|  |             Mat gray = src.CvtColor(ColorConversionCodes.BGR2GRAY); | ||||||
|  |             //二值化 | ||||||
|  |             Mat binary = gray.Threshold(0, 255, ThresholdTypes.Otsu | ThresholdTypes.Binary); | ||||||
|  |  | ||||||
|  |             //求轮廓 不连通会有多个闭合区域 | ||||||
|  |             OpenCvSharp.Point[][] contours; | ||||||
|  |             HierarchyIndex[] hierarchy; | ||||||
|  |             Cv2.FindContours(binary, out contours, out hierarchy, RetrievalModes.List, ContourApproximationModes.ApproxSimple); | ||||||
|  |             for (int i = 0; i < contours.Count(); i++) | ||||||
|  |             { | ||||||
|  |                 //所有面积相加 | ||||||
|  |                 Area += Cv2.ContourArea(contours[i], false); | ||||||
|  |             } | ||||||
|  |             return Area; | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
| @@ -4,7 +4,7 @@ using System.Linq; | |||||||
| using System.Text; | using System.Text; | ||||||
| using System.Threading.Tasks; | using System.Threading.Tasks; | ||||||
|  |  | ||||||
| namespace XKRS.Device.SolidMotionCard | namespace DH.Devices.Motion | ||||||
| { | { | ||||||
|  |  | ||||||
|     public enum FuncRet |     public enum FuncRet | ||||||
|   | |||||||
| @@ -73,7 +73,7 @@ namespace DH.Devices.Motion | |||||||
|         [Category("机台配置")] |         [Category("机台配置")] | ||||||
|         [DisplayName("机台类型")] |         [DisplayName("机台类型")] | ||||||
|         [Description("机台类型")] |         [Description("机台类型")] | ||||||
|         public MachineDiskType MachineDiskType { get; set; } = MachineDiskType.DoubleDisk; |         public MachineDiskType MachineDiskType { get; set; } = MachineDiskType.SingleDisk; | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
| @@ -111,12 +111,12 @@ namespace DH.Devices.Motion | |||||||
|         [DisplayName("输出IO总数")] |         [DisplayName("输出IO总数")] | ||||||
|         public int OutputNums { get; set; } = 16; |         public int OutputNums { get; set; } = 16; | ||||||
|  |  | ||||||
|         //[Category("IO配置")] |         [Category("IO配置")] | ||||||
|         //[DisplayName("IO定义集合")] |         [DisplayName("IO定义集合")] | ||||||
|         //[Description("IO定义集合")] |         [Description("IO定义集合")] | ||||||
|         //[TypeConverter(typeof(CollectionCountConvert))] |         //[TypeConverter(typeof(CollectionCountConvert))] | ||||||
|         //[Editor(typeof(ComplexCollectionEditor<IODefinition>), typeof(UITypeEditor))] |        // [Editor(typeof(ComplexCollectionEditor<IODefinition>), typeof(UITypeEditor))] | ||||||
|         //public List<IODefinition> IODefinitionCollection { get; set; } = new List<IODefinition>(); |         public List<IODefinition> IODefinitionCollection { get; set; } = new List<IODefinition>(); | ||||||
|  |  | ||||||
|         [Category("IO配置")] |         [Category("IO配置")] | ||||||
|         [DisplayName("是否信号模式")] |         [DisplayName("是否信号模式")] | ||||||
| @@ -194,35 +194,35 @@ namespace DH.Devices.Motion | |||||||
|         public List<BlowSetting> BlowSettings { get; set; } = new List<BlowSetting>(); |         public List<BlowSetting> BlowSettings { get; set; } = new List<BlowSetting>(); | ||||||
|  |  | ||||||
|  |  | ||||||
|         //[Category("筛选配置")] |         [Category("筛选配置")] | ||||||
|         //[DisplayName("转盘运转方向")] |         [DisplayName("转盘运转方向")] | ||||||
|         //[Description("转盘运转方向,顺时针或逆时针")] |         [Description("转盘运转方向,顺时针或逆时针")] | ||||||
|         //[TypeConverter(typeof(EnumDescriptionConverter<RotationDirectionEnum>))] |         //[TypeConverter(typeof(EnumDescriptionConverter<RotationDirectionEnum>))] | ||||||
|         //public RotationDirectionEnum MotionDir { get; set; } = RotationDirectionEnum.Clockwise; |         public RotationDirectionEnum MotionDir { get; set; } = RotationDirectionEnum.Clockwise; | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|         [Category("筛选配置")] |         [Category("筛选配置")] | ||||||
|         [DisplayName("物料尺寸最大值")] |         [DisplayName("物料尺寸最大值")] | ||||||
|         [Description("物料尺寸最大值,单位:脉冲")] |         [Description("物料尺寸最大值,单位:脉冲")] | ||||||
|         public uint PieceMaxSize { get; set; } = 2000; |         public uint PieceMaxSize { get; set; } = 20000; | ||||||
|  |  | ||||||
|  |  | ||||||
|         [Category("筛选配置")] |         [Category("筛选配置")] | ||||||
|         [DisplayName("物料尺寸最小值")] |         [DisplayName("物料尺寸最小值")] | ||||||
|         [Description("物料尺寸最小值,单位:脉冲")] |         [Description("物料尺寸最小值,单位:脉冲")] | ||||||
|         public uint PieceMinSize { get; set; } = 1500; |         public uint PieceMinSize { get; set; } = 10; | ||||||
|  |  | ||||||
|  |  | ||||||
|         [Category("筛选配置")] |         [Category("筛选配置")] | ||||||
|         [DisplayName("物料最小间隔")] |         [DisplayName("物料最小间隔")] | ||||||
|         [Description("物料最小间隔,单位:脉冲")] |         [Description("物料最小间隔,单位:脉冲")] | ||||||
|         public uint MinDistance { get; set; } = 2000; |         public uint MinDistance { get; set; } = 10; | ||||||
|  |  | ||||||
|         [Category("筛选配置")] |         [Category("筛选配置")] | ||||||
|         [DisplayName("两个物料之间触发最小间隔时间")] |         [DisplayName("两个物料之间触发最小间隔时间")] | ||||||
|         [Description("两个物料之间触发最小间隔时间,单位:ms")] |         [Description("两个物料之间触发最小间隔时间,单位:ms")] | ||||||
|         public uint MinTimeInterval { get; set; } = 10; |         public uint MinTimeInterval { get; set; } = 1; | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
| @@ -550,7 +550,7 @@ namespace DH.Devices.Motion | |||||||
|         [Category("回原点参数")] |         [Category("回原点参数")] | ||||||
|         [DisplayName("回原点方式")] |         [DisplayName("回原点方式")] | ||||||
|         [Description("HomeMode:回原点方式")] |         [Description("HomeMode:回原点方式")] | ||||||
|         public GoHomeMode HomeMode { get; set; } = GoHomeMode.Negative_Ne_Center_H_Positive_N_Stop_HNeO_Offset_Po; |         public GoHomeMode HomeMode { get; set; } = GoHomeMode.Negative_Ne_Center_H_Positive_N_Index_HPoO_Offset_Po; | ||||||
|  |  | ||||||
|  |  | ||||||
|         [Category("回原点参数")] |         [Category("回原点参数")] | ||||||
|   | |||||||
| @@ -2,9 +2,10 @@ | |||||||
| using DH.Devices.Motion; | using DH.Devices.Motion; | ||||||
| using MCDLL_NET; | using MCDLL_NET; | ||||||
| using System.Diagnostics; | using System.Diagnostics; | ||||||
|  | using static System.Collections.Specialized.BitVector32; | ||||||
|  |  | ||||||
|  |  | ||||||
| namespace XKRS.Device.SolidMotionCard | namespace DH.Devices.Motion | ||||||
| { | { | ||||||
|  |  | ||||||
|  |  | ||||||
| @@ -150,20 +151,30 @@ namespace XKRS.Device.SolidMotionCard | |||||||
|                     .ToDictionary(a => a.AxisIndex, a => new ManualResetEvent(true)); |                     .ToDictionary(a => a.AxisIndex, a => new ManualResetEvent(true)); | ||||||
|  |  | ||||||
|                 // 初始化时关闭所有轴,停止筛选 begin ======= |                 // 初始化时关闭所有轴,停止筛选 begin ======= | ||||||
|                 AllMoveStop(); |                 //AllMoveStop(); | ||||||
|                 AllAxisOff(); |                | ||||||
|  |                  //  CMCDLL_NET.MCF_Axis_Stop_Net(0, AxisStopMode.AxisStopIMD, 0); | ||||||
|  |               | ||||||
|  |                  //CMCDLL_NET.MCF_Set_Axis_Stop_Profile_Net(0, 50000, 0, 0, 0); | ||||||
|  |                  // CMCDLL_NET.MCF_Axis_Stop_Net(0, AxisStopMode.AxisStopDEC, 0); | ||||||
|  |                 AxisStop(); | ||||||
|  |                 //AllAxisOff(); | ||||||
|  |                 var ret = CMCDLL_NET.MCF_Set_Servo_Enable_Net(0, (ushort)ServoLogic.Servo_Open, 0); | ||||||
|  |  | ||||||
|                 StopSorting(); |                 StopSorting(); | ||||||
|  |  | ||||||
|                 // 初始化时关闭所有轴,停止筛选 end =======  |                 // 初始化时关闭所有轴,停止筛选 end =======  | ||||||
|  |  | ||||||
|                 AllAxisOn(); |                 //AllAxisOn(); | ||||||
|                 Start(); |                 Start(); | ||||||
|                 MonitorPosition(); |                 MonitorPosition(); | ||||||
|                 MonitorAxisStatus(); |                 MonitorAxisStatus(); | ||||||
|                 MonitorPieces(); |                 | ||||||
|  |  | ||||||
|                 CustomStart(); |                 CustomStart(); | ||||||
|  |                  | ||||||
|  |  | ||||||
|  |                 MonitorPieces(); | ||||||
|                 isconnected = true; |                 isconnected = true; | ||||||
|  |  | ||||||
|             } |             } | ||||||
| @@ -409,8 +420,10 @@ namespace XKRS.Device.SolidMotionCard | |||||||
|         public override void Stop() |         public override void Stop() | ||||||
|         { |         { | ||||||
|             //base.Stop(); |             //base.Stop(); | ||||||
|             AllMoveStop(); |             AxisStop(); | ||||||
|             AllAxisOff(); |             int ret = CMCDLL_NET.MCF_Set_Servo_Enable_Net(0, (ushort)ServoLogic.Servo_Open, 0); | ||||||
|  |  | ||||||
|  |            // AllAxisOff(); | ||||||
|  |  | ||||||
|             for (ushort station = 0; station < BoardCount; station++) |             for (ushort station = 0; station < BoardCount; station++) | ||||||
|             { |             { | ||||||
| @@ -849,7 +862,14 @@ namespace XKRS.Device.SolidMotionCard | |||||||
|                 return ret == (short)FuncRet.Function_Success; |                 return ret == (short)FuncRet.Function_Success; | ||||||
|             }); |             }); | ||||||
|         } |         } | ||||||
|  |         //方案2:不使用外部文本框输入参数,直接写入参数 | ||||||
|         |         | ||||||
|  |         public void JOGRun(double MaxV,double MaxA) | ||||||
|  |         { | ||||||
|  |             int ret = CMCDLL_NET.MCF_Set_Pulse_Mode_Net(0, (ushort)PulseMode.Pulse_Dir_H, 0); | ||||||
|  |             ret = CMCDLL_NET.MCF_Set_Servo_Enable_Net(0, (ushort)ServoLogic.Servo_Close, 0); | ||||||
|  |             ret=CMCDLL_NET.MCF_JOG_Net(0, MaxV, MaxA, 0); | ||||||
|  |         } | ||||||
|         /// <summary> |         /// <summary> | ||||||
|         /// 点位到点位运动 |         /// 点位到点位运动 | ||||||
|         /// </summary> |         /// </summary> | ||||||
| @@ -1381,6 +1401,31 @@ namespace XKRS.Device.SolidMotionCard | |||||||
|             } |             } | ||||||
|         } |         } | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  |         public void AxisStop() | ||||||
|  |         { | ||||||
|  |             short rtn; | ||||||
|  |             ushort StationNumber = 0; | ||||||
|  |             for (ushort a = 0; a < 4; a++) | ||||||
|  |             { | ||||||
|  |                 rtn = CMCDLL_NET.MCF_Set_Axis_Stop_Profile_Net(a, 10000, 100000, 1, StationNumber);//设置轴S型停止曲线参数 | ||||||
|  |                 rtn = CMCDLL_NET.MCF_Axis_Stop_Net(a, 1, StationNumber);//设置轴为平滑停止模式 | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |         public  bool CArdReset() | ||||||
|  |         { | ||||||
|  |  | ||||||
|  |            // ConvertFromAxis(startAxisIndex, out ushort station, out ushort axis); | ||||||
|  |  | ||||||
|  |             var ret = CMCDLL_NET.MCF_Set_Position_Net(0, 0, 0); | ||||||
|  |             var ret2 = CMCDLL_NET.MCF_Set_Encoder_Net(0, 0, 0); | ||||||
|  |              | ||||||
|  |             return ret2 == 0 ? true : false;  | ||||||
|  |  | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |  | ||||||
|         /// <summary> |         /// <summary> | ||||||
|         /// 某个轴运动停止 |         /// 某个轴运动停止 | ||||||
|         /// </summary> |         /// </summary> | ||||||
|   | |||||||
| @@ -14,6 +14,7 @@ | |||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|   <ItemGroup> |   <ItemGroup> | ||||||
|     <PackageReference Include="Newtonsoft.Json" Version="13.0.3" /> |     <PackageReference Include="Newtonsoft.Json" Version="13.0.3" /> | ||||||
|     <PackageReference Include="OpenCvSharp4" Version="4.10.0.20241108" /> |     <PackageReference Include="OpenCvSharp4" Version="4.10.0.20241108" /> | ||||||
|   | |||||||
| @@ -324,6 +324,29 @@ namespace DH.Devices.Vision | |||||||
|         [Description("是否加入检测工位")] |         [Description("是否加入检测工位")] | ||||||
|         public bool IsAddStation { get; set; } = true; |         public bool IsAddStation { get; set; } = true; | ||||||
|  |  | ||||||
|  |         [Category("1.预处理(视觉算子)")] | ||||||
|  |         [DisplayName("预处理-算法文件路径")] | ||||||
|  |        // [Description("预处理算法文件路径配置")][Editor(typeof(FileDialogEditor), typeof(UITypeEditor))] | ||||||
|  |         public string HalconAlgorithemPath_Pre { get; set; } | ||||||
|  |  | ||||||
|  |        // [Category("1.预处理(视觉算子)")] | ||||||
|  |         //[DisplayName("预处理-输出结果的SPEC标准")] | ||||||
|  |         //[Description("预处理输出结果的SPEC标准配置")] | ||||||
|  |         | ||||||
|  |        // public List<IndexedSpec> OutputSpec_Pre { get; set; } = new List<IndexedSpec>(); | ||||||
|  |  | ||||||
|  |         [Category("1.预处理(视觉算子)")] | ||||||
|  |         [DisplayName("预处理-参数列表")] | ||||||
|  |         [Description("预处理-参数列表")] | ||||||
|  |         | ||||||
|  |         public List<PreTreatParam> PreTreatParams { get; set; } = new List<PreTreatParam>(); | ||||||
|  |  | ||||||
|  |         [Category("1.预处理(视觉算子)")] | ||||||
|  |         [DisplayName("预处理-输出参数列表")] | ||||||
|  |         [Description("预处理-输出参数列表")] | ||||||
|  |  | ||||||
|  |         public List<PreTreatParam> OUTPreTreatParams { get; set; } = new List<PreTreatParam>(); | ||||||
|  |  | ||||||
|         [Category("2.中检测(深度学习)")] |         [Category("2.中检测(深度学习)")] | ||||||
|         [DisplayName("中检测-模型类型")] |         [DisplayName("中检测-模型类型")] | ||||||
|         [Description("模型类型:ImageClassification-图片分类;ObjectDetection:目标检测;Segmentation-图像分割")] |         [Description("模型类型:ImageClassification-图片分类;ObjectDetection:目标检测;Segmentation-图像分割")] | ||||||
|   | |||||||
| @@ -2,6 +2,7 @@ | |||||||
| using OpenCvSharp; | using OpenCvSharp; | ||||||
| using System; | using System; | ||||||
| using System.Collections.Generic; | using System.Collections.Generic; | ||||||
|  | using System.ComponentModel; | ||||||
| using System.Drawing; | using System.Drawing; | ||||||
| using System.Runtime.InteropServices; | using System.Runtime.InteropServices; | ||||||
|  |  | ||||||
| @@ -85,6 +86,30 @@ namespace DH.Devices.Vision | |||||||
|  |  | ||||||
|         } |         } | ||||||
|  |  | ||||||
|  |     } | ||||||
|  |     public class PreTreatParam  | ||||||
|  |     { | ||||||
|  |  | ||||||
|  |         /// <summary> | ||||||
|  |         /// 参数名称 | ||||||
|  |         /// </summary> | ||||||
|  |         ///      | ||||||
|  |         [Category("预处理参数")] | ||||||
|  |         [DisplayName("参数名称")] | ||||||
|  |         [Description("参数名称")] | ||||||
|  |         public string Name { get; set; } | ||||||
|  |  | ||||||
|  |  | ||||||
|  |         /// <summary> | ||||||
|  |         /// 参数值 | ||||||
|  |         /// </summary> | ||||||
|  |         ///      | ||||||
|  |         [Category("预处理参数")] | ||||||
|  |         [DisplayName("参数值")] | ||||||
|  |         [Description("参数值")] | ||||||
|  |         public string Value { get; set; } | ||||||
|  |  | ||||||
|  |         | ||||||
|     } |     } | ||||||
|     public static class MLGPUEngine |     public static class MLGPUEngine | ||||||
|     { |     { | ||||||
|   | |||||||
							
								
								
									
										35
									
								
								DH.Devices.Vision/SimboVisionModel.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										35
									
								
								DH.Devices.Vision/SimboVisionModel.cs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,35 @@ | |||||||
|  |  | ||||||
|  | using System; | ||||||
|  | using System.Collections.Generic; | ||||||
|  | using System.Linq; | ||||||
|  | using System.Text; | ||||||
|  | using System.Threading.Tasks; | ||||||
|  |  | ||||||
|  | namespace DH.Devices.Vision | ||||||
|  | { | ||||||
|  |     //工站 模型检测引擎 | ||||||
|  |     public class SimboStationMLEngineSet | ||||||
|  |     { | ||||||
|  |         public bool IsUseGPU { get; set; } | ||||||
|  |         /// <summary> | ||||||
|  |         /// GPU设备号 | ||||||
|  |         /// </summary> | ||||||
|  |         public int GPUNo { get; set; } | ||||||
|  |         /// <summary> | ||||||
|  |         /// CPU线程号 | ||||||
|  |         /// </summary> | ||||||
|  |         public int CPUNo { get; set; } | ||||||
|  |         /// <summary> | ||||||
|  |         /// 检测配置ID | ||||||
|  |         /// </summary> | ||||||
|  |         public string DetectionId { get; set; } | ||||||
|  |  | ||||||
|  |         public string DetectionName { get; set; } | ||||||
|  |  | ||||||
|  |         /// <summary> | ||||||
|  |         /// 深度学习模型 | ||||||
|  |         /// </summary> | ||||||
|  |         public SimboVisionMLBase StationMLEngine { get; set; } | ||||||
|  |  | ||||||
|  |     } | ||||||
|  | } | ||||||
| @@ -19,6 +19,7 @@ | |||||||
|  |  | ||||||
|   <ItemGroup> |   <ItemGroup> | ||||||
|     <ProjectReference Include="..\DH.Devices.Camera\DH.Devices.Camera.csproj" /> |     <ProjectReference Include="..\DH.Devices.Camera\DH.Devices.Camera.csproj" /> | ||||||
|  |     <ProjectReference Include="..\DH.Devices.Motion\DH.Devices.Motion.csproj" /> | ||||||
|     <ProjectReference Include="..\DH.Devices.PLC\DH.Devices.PLC.csproj" /> |     <ProjectReference Include="..\DH.Devices.PLC\DH.Devices.PLC.csproj" /> | ||||||
|     <ProjectReference Include="..\DH.Devices.Vision\DH.Devices.Vision.csproj" /> |     <ProjectReference Include="..\DH.Devices.Vision\DH.Devices.Vision.csproj" /> | ||||||
|   </ItemGroup> |   </ItemGroup> | ||||||
| @@ -27,6 +28,12 @@ | |||||||
|     <Reference Include="DVPCameraCS64"> |     <Reference Include="DVPCameraCS64"> | ||||||
|       <HintPath>..\x64\Debug\DVPCameraCS64.dll</HintPath> |       <HintPath>..\x64\Debug\DVPCameraCS64.dll</HintPath> | ||||||
|     </Reference> |     </Reference> | ||||||
|  |     <Reference Include="halcondotnet"> | ||||||
|  |       <HintPath>..\x64\Debug\halcondotnet.dll</HintPath> | ||||||
|  |     </Reference> | ||||||
|  |     <Reference Include="hdevenginedotnet"> | ||||||
|  |       <HintPath>..\x64\Debug\hdevenginedotnet.dll</HintPath> | ||||||
|  |     </Reference> | ||||||
|   </ItemGroup> |   </ItemGroup> | ||||||
|  |  | ||||||
| </Project> | </Project> | ||||||
| @@ -1,12 +1,15 @@ | |||||||
| using AntdUI; | using AntdUI; | ||||||
| using AntdUI.Svg; | using AntdUI.Svg; | ||||||
|  | using DH.Commons.Enums; | ||||||
| using DH.Devices.Camera; | using DH.Devices.Camera; | ||||||
|  | using DH.Devices.Motion; | ||||||
| using DH.Devices.PLC; | using DH.Devices.PLC; | ||||||
| using DH.Devices.Vision; | using DH.Devices.Vision; | ||||||
| using DHSoftware.Languages; | using DHSoftware.Languages; | ||||||
| using DHSoftware.Models; | using DHSoftware.Models; | ||||||
| using DHSoftware.Utils; | using DHSoftware.Utils; | ||||||
| using DVPCameraType; | using DVPCameraType; | ||||||
|  | using HalconDotNet; | ||||||
| using Microsoft.Win32; | using Microsoft.Win32; | ||||||
| using OpenCvSharp; | using OpenCvSharp; | ||||||
| using System; | using System; | ||||||
| @@ -21,6 +24,7 @@ using System.Text; | |||||||
| using System.Threading; | using System.Threading; | ||||||
| using System.Threading.Tasks; | using System.Threading.Tasks; | ||||||
| using System.Windows.Forms; | using System.Windows.Forms; | ||||||
|  | using XKRS.Common.Model; | ||||||
| using static AntdUI.Math3D; | using static AntdUI.Math3D; | ||||||
| using Camera = DHSoftware.Models.Camera; | using Camera = DHSoftware.Models.Camera; | ||||||
|  |  | ||||||
| @@ -215,6 +219,7 @@ namespace DHSoftware | |||||||
|         public List<Do3ThinkCamera> Cameras { get; } = new List<Do3ThinkCamera>(); |         public List<Do3ThinkCamera> Cameras { get; } = new List<Do3ThinkCamera>(); | ||||||
|         public Dictionary<string, SimboObjectDetection> Dectection { get; } = new Dictionary<string, SimboObjectDetection>(); |         public Dictionary<string, SimboObjectDetection> Dectection { get; } = new Dictionary<string, SimboObjectDetection>(); | ||||||
|         public XinJEPLCTcpNet PLC { get; } = new XinJEPLCTcpNet(); |         public XinJEPLCTcpNet PLC { get; } = new XinJEPLCTcpNet(); | ||||||
|  |         SLDMotion sLDMotion = new SLDMotion(); | ||||||
|         private void MainWindow_Load(object sender, EventArgs e) |         private void MainWindow_Load(object sender, EventArgs e) | ||||||
|         { |         { | ||||||
|  |  | ||||||
| @@ -264,9 +269,11 @@ namespace DHSoftware | |||||||
|         public volatile int ProductNum_Total = 0; |         public volatile int ProductNum_Total = 0; | ||||||
|         public volatile int ProductNum_OK = 0; |         public volatile int ProductNum_OK = 0; | ||||||
|         private readonly object _cameraSummaryLock = new object(); |         private readonly object _cameraSummaryLock = new object(); | ||||||
|         List<DetectionConfig> detectionList = new List<DetectionConfig>(); |         List<DetectionConfig> DetectionConfigs = new List<DetectionConfig>(); | ||||||
|  |         List<SimboStationMLEngineSet> SimboStationMLEngineList = new List<SimboStationMLEngineSet>(); | ||||||
|  |         Dictionary<string, HDevEngineTool> HalconToolDict = new Dictionary<string, HDevEngineTool>(); | ||||||
|         public List<RecongnitionLabel> RecongnitionLabelList { get; set; } = new List<RecongnitionLabel>(); |         public List<RecongnitionLabel> RecongnitionLabelList { get; set; } = new List<RecongnitionLabel>(); | ||||||
|         public DateTime sraerttime; |         public DateTime startTime; | ||||||
|         private void HandleStartButton() |         private void HandleStartButton() | ||||||
|         { |         { | ||||||
|             CurrentMachine = true; |             CurrentMachine = true; | ||||||
| @@ -299,10 +306,14 @@ namespace DHSoftware | |||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|             var det1 = new DetectionConfig("相机1", MLModelType.ObjectDetection, @"D:\DHSoftware\DHSoftware\Models\yolov3.cfg", false, "Cam1"); |             var det1 = new DetectionConfig("相机1", MLModelType.ObjectDetection, @"D:\PROJECTS\X015\Vision\Cam1.onnx", false, "Cam1"); | ||||||
|             var det2 = new DetectionConfig("相机2", MLModelType.ObjectDetection, @"D:\DHSoftware\DHSoftware\Models\yolov3.cfg", false, "Cam2"); |             var det2 = new DetectionConfig("相机2", MLModelType.ObjectDetection, @"D:\PROJECTS\X015\Vision\Cam2.onnx", false, "Cam2"); | ||||||
|             var det3 = new DetectionConfig("相机3", MLModelType.ObjectDetection, @"D:\DHSoftware\DHSoftware\Models\yolov3.cfg", false, "Cam3"); |             var det3 = new DetectionConfig("相机3", MLModelType.ObjectDetection, @"D:\PROJECTS\X015\Vision\Cam3.onnx", false, "Cam3"); | ||||||
|             var det4 = new DetectionConfig("相机4", MLModelType.ObjectDetection, @"D:\DHSoftware\DHSoftware\Models\yolov3.cfg", false, "Cam4"); |             var det4 = new DetectionConfig("相机4", MLModelType.ObjectDetection, @"D:\PROJECTS\X015\Vision\Cam4.onnx", false, "Cam4"); | ||||||
|  |             var det5 = new DetectionConfig("相机5", MLModelType.ObjectDetection, @"D:\PROJECTS\X015\Vision\Cam5.onnx", false, "Cam5"); | ||||||
|  |             var det6 = new DetectionConfig("相机6", MLModelType.ObjectDetection, @"D:\PROJECTS\X015\Vision\Cam6.onnx", false, "Cam6"); | ||||||
|  |             var det7 = new DetectionConfig("相机7", MLModelType.ObjectDetection, @"D:\PROJECTS\X015\Vision\Cam7.onnx", false, "Cam7"); | ||||||
|  |             var det8 = new DetectionConfig("相机8", MLModelType.ObjectDetection, @"D:\PROJECTS\X015\Vision\Cam8.onnx", false, "Cam8"); | ||||||
|             List<RelatedCamera> CameraCollects=new List<RelatedCamera>(); |             List<RelatedCamera> CameraCollects=new List<RelatedCamera>(); | ||||||
|             CameraCollects.Add(new RelatedCamera("Cam1")); |             CameraCollects.Add(new RelatedCamera("Cam1")); | ||||||
|             List<RelatedCamera> CameraCollects2 = new List<RelatedCamera>(); |             List<RelatedCamera> CameraCollects2 = new List<RelatedCamera>(); | ||||||
| @@ -313,43 +324,125 @@ namespace DHSoftware | |||||||
|             CameraCollects4.Add(new RelatedCamera("Cam4")); |             CameraCollects4.Add(new RelatedCamera("Cam4")); | ||||||
|             List<RelatedCamera> CameraCollects5 = new List<RelatedCamera>(); |             List<RelatedCamera> CameraCollects5 = new List<RelatedCamera>(); | ||||||
|             CameraCollects5.Add(new RelatedCamera("Cam5")); |             CameraCollects5.Add(new RelatedCamera("Cam5")); | ||||||
|  |             List<RelatedCamera> CameraCollects6 = new List<RelatedCamera>(); | ||||||
|  |             CameraCollects6.Add(new RelatedCamera("Cam6")); | ||||||
|  |             List<RelatedCamera> CameraCollects7 = new List<RelatedCamera>(); | ||||||
|  |             CameraCollects7.Add(new RelatedCamera("Cam7")); | ||||||
|  |             List<RelatedCamera> CameraCollects8 = new List<RelatedCamera>(); | ||||||
|  |             CameraCollects8.Add(new RelatedCamera("Cam8")); | ||||||
|  |  | ||||||
|             float Conf = 0.5f; |             float Conf = 0.5f; | ||||||
|  |  | ||||||
|  |  | ||||||
|             det1.CameraCollects = CameraCollects; |             det1.CameraCollects = CameraCollects; | ||||||
|             det1.ModelconfThreshold = Conf; |             det1.ModelconfThreshold = Conf; | ||||||
|             det1.ModelWidth = 640; |             det1.ModelWidth = 640; | ||||||
|             det1.ModelHeight = 640; |             det1.ModelHeight = 640; | ||||||
|             det1.in_lable_path = " D:\\PROJECTS\\MaodingTest1\\Vision\\cam1.txt"; |             det1.in_lable_path = "D:\\PROJECTS\\X015\\Vision\\Cam1.txt"; | ||||||
|  |             det1.IsEnabled = true; | ||||||
|  |  | ||||||
|             det2.CameraCollects = CameraCollects2; |             det2.CameraCollects = CameraCollects2; | ||||||
|             det2.ModelconfThreshold = Conf; |             det2.ModelconfThreshold = Conf; | ||||||
|             det2.ModelWidth = 640; |             det2.ModelWidth = 640; | ||||||
|             det2.ModelHeight = 640; |             det2.ModelHeight = 640; | ||||||
|             det2.in_lable_path = " D:\\PROJECTS\\MaodingTest1\\Vision\\cam2.txt"; |             det2.in_lable_path = "D:\\PROJECTS\\X015\\Vision\\Cam2.txt"; | ||||||
|  |             det2.IsEnabled = true; | ||||||
|  |  | ||||||
|             det3.CameraCollects = CameraCollects3; |             det3.CameraCollects = CameraCollects3; | ||||||
|             det3.ModelconfThreshold = Conf; |             det3.ModelconfThreshold = Conf; | ||||||
|             det3.ModelWidth = 640; |             det3.ModelWidth = 640; | ||||||
|             det3.ModelHeight = 640; |             det3.ModelHeight = 640; | ||||||
|             det3.in_lable_path = " D:\\PROJECTS\\MaodingTest1\\Vision\\cam3.txt"; |             det3.in_lable_path = "D:\\PROJECTS\\X015\\Vision\\Cam3.txt"; | ||||||
|  |             det3.IsEnabled = true; | ||||||
|  |  | ||||||
|             det4.CameraCollects = CameraCollects4; |             det4.CameraCollects = CameraCollects4; | ||||||
|             det4.ModelconfThreshold = Conf; |             det4.ModelconfThreshold = Conf; | ||||||
|             det4.ModelWidth = 640; |             det4.ModelWidth = 640; | ||||||
|             det4.ModelHeight = 640; |             det4.ModelHeight = 640; | ||||||
|             det4.in_lable_path = " D:\\PROJECTS\\MaodingTest1\\Vision\\cam4.txt"; |             det4.in_lable_path = "D:\\PROJECTS\\X015\\Vision\\Cam4.txt"; | ||||||
|  |             det4.IsEnabled = true; | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  |             det5.CameraCollects = CameraCollects5; | ||||||
|  |             det5.ModelconfThreshold = Conf; | ||||||
|  |             det5.ModelWidth = 640; | ||||||
|  |             det5.ModelHeight = 640; | ||||||
|  |             det5.in_lable_path = "D:\\PROJECTS\\X015\\Vision\\Cam5.txt"; | ||||||
|  |             det5.IsEnabled = true; | ||||||
|  |  | ||||||
|  |             det6.CameraCollects = CameraCollects6; | ||||||
|  |             det6.ModelconfThreshold = Conf; | ||||||
|  |             det6.ModelWidth = 640; | ||||||
|  |             det6.ModelHeight = 640; | ||||||
|  |             det6.in_lable_path = "D:\\PROJECTS\\X015\\Vision\\Cam6.txt"; | ||||||
|  |             det6.IsEnabled = true; | ||||||
|  |  | ||||||
|  |             det7.CameraCollects = CameraCollects7; | ||||||
|  |             det7.ModelconfThreshold = Conf; | ||||||
|  |             det7.ModelWidth = 640; | ||||||
|  |             det7.ModelHeight = 640; | ||||||
|  |             det7.in_lable_path = "D:\\PROJECTS\\X015\\Vision\\Cam7.txt"; | ||||||
|  |             det7.IsEnabled = true; | ||||||
|  |  | ||||||
|  |             det8.CameraCollects = CameraCollects8; | ||||||
|  |             det8.ModelconfThreshold = Conf; | ||||||
|  |             det8.ModelWidth = 640; | ||||||
|  |             det8.ModelHeight = 640; | ||||||
|  |             det8.in_lable_path = "D:\\PROJECTS\\X015\\Vision\\Cam8.txt"; | ||||||
|  |             det8.IsEnabled = true; | ||||||
|  |  | ||||||
|  |             DetectionConfigs.Add(det1); | ||||||
|  |             DetectionConfigs.Add(det2); | ||||||
|  |             DetectionConfigs.Add(det3); | ||||||
|  |             DetectionConfigs.Add(det4); | ||||||
|  |             DetectionConfigs.Add(det5); | ||||||
|  |             DetectionConfigs.Add(det6); | ||||||
|  |             DetectionConfigs.Add(det7); | ||||||
|  |             DetectionConfigs.Add(det8); | ||||||
|  |  | ||||||
|             detectionList.Add(det1); |  | ||||||
|             detectionList.Add(det2); |  | ||||||
|             detectionList.Add(det3); |  | ||||||
|             detectionList.Add(det4); |  | ||||||
|             Cameras.Clear(); |             Cameras.Clear(); | ||||||
|             HKCameras.Clear(); |             HKCameras.Clear(); | ||||||
|             Dectection.Clear(); |             Dectection.Clear(); | ||||||
|             _cameraRelatedDetectionDict = new(); |             _cameraRelatedDetectionDict = new(); | ||||||
|  |  | ||||||
|  | #if false | ||||||
|  |             for (int i = 1; i <= 8; i++) | ||||||
|  |             { | ||||||
|  |                 HikVisionCamera camera = new HikVisionCamera(); | ||||||
|  |                 camera.CameraName = $"Cam{i}"; | ||||||
|  |                 camera.CameraIP = $"192.168.{i}.1"; | ||||||
|  |                 camera.ComputerIP = $"192.168.{i}.1"; | ||||||
|  |                 camera.CameraConnect(); | ||||||
|  |                 camera.OnHImageOutput += OnCameraHImageOutput; | ||||||
|  |                 HKCameras.Add(camera); | ||||||
|  |  | ||||||
|             detectionList.ForEach(detection => |  | ||||||
|  |             } | ||||||
|  | #else | ||||||
|  |             Do3ThinkCamera do3ThinkCamera1 = new Do3ThinkCamera(); | ||||||
|  |  | ||||||
|  |             do3ThinkCamera1.dvpStreamFormat = dvpStreamFormat.S_RAW8; | ||||||
|  |             do3ThinkCamera1.CameraName = "Cam1"; | ||||||
|  |             do3ThinkCamera1.CameraConnect(); | ||||||
|  |             do3ThinkCamera1.OnHImageOutput += OnCameraHImageOutput; | ||||||
|  |             Cameras.Add(do3ThinkCamera1); | ||||||
|  |             for (int i=2;i<=8;i++) | ||||||
|  |             { | ||||||
|  |  | ||||||
|  |                 Do3ThinkCamera do3ThinkCamera2 = new Do3ThinkCamera(); | ||||||
|  |                 do3ThinkCamera2.dvpStreamFormat = dvpStreamFormat.S_RGB24; | ||||||
|  |                 do3ThinkCamera2.CameraName = $"Cam{i}"; | ||||||
|  |                 Cameras.Add(do3ThinkCamera2); | ||||||
|  |                 do3ThinkCamera2.CameraConnect(); | ||||||
|  |                 do3ThinkCamera2.OnHImageOutput += OnCameraHImageOutput; | ||||||
|  |             } | ||||||
|  |             | ||||||
|  |  | ||||||
|  | #endif | ||||||
|  |  | ||||||
|  |  | ||||||
|  |             DetectionConfigs.ForEach(detection => | ||||||
|             { |             { | ||||||
|  |  | ||||||
|                  detection.CameraCollects.ForEach(cam => |                  detection.CameraCollects.ForEach(cam => | ||||||
| @@ -372,84 +465,117 @@ namespace DHSoftware | |||||||
|                 ); |                 ); | ||||||
|             }); |             }); | ||||||
|             string inferenceDevice = "CPU"; |             string inferenceDevice = "CPU"; | ||||||
|             //for (int i = 1; i <= 8; i++) |  | ||||||
|             //{ |  | ||||||
|             //    HikVisionCamera camera = new HikVisionCamera(); |  | ||||||
|             //    camera.CameraName = $"Cam{i}"; |  | ||||||
|             //    camera.CameraIP = $"192.168.{i}.1"; |  | ||||||
|             //    camera.ComputerIP = $"192.168.{i}.1"; |  | ||||||
|             //    camera.CameraConnect(); |  | ||||||
|             //    camera.OnHImageOutput += OnCameraHImageOutput; |  | ||||||
|             //    HKCameras.Add(camera); |  | ||||||
|             //    var simbo_1 = new SimboObjectDetection |  | ||||||
|             //    { |  | ||||||
|  |  | ||||||
|             //    }; |  | ||||||
|             //    MLInit mLInit_1; |  | ||||||
|  |  | ||||||
|  |  | ||||||
|             //    mLInit_1 = new MLInit($"D:\\PROJECTS\\MaodingTest1\\Vision\\cam{i}.onnx", "images", inferenceDevice, 640, 640); |  | ||||||
|  |  | ||||||
|  |  | ||||||
|             //    simbo_1.Load(mLInit_1); |  | ||||||
|             //    Dectection.Add(camera.CameraName, simbo_1); |  | ||||||
|             //} |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|             //Add the code for the "启动" button click here |             //Add the code for the "启动" button click here | ||||||
|             Do3ThinkCamera do3ThinkCamera1 = new Do3ThinkCamera(); |  | ||||||
|  |  | ||||||
|             do3ThinkCamera1.dvpStreamFormat = dvpStreamFormat.S_MONO8; |             //初始化Halcon工具 | ||||||
|             do3ThinkCamera1.CameraName = "Cam1"; |             InitialHalconTools(); | ||||||
|             Do3ThinkCamera do3ThinkCamera2 = new Do3ThinkCamera(); |  | ||||||
|              |              | ||||||
|             do3ThinkCamera2.dvpStreamFormat = dvpStreamFormat.S_RGB24; |             //深度学习模型加载 | ||||||
|             do3ThinkCamera2.CameraName = "Cam2"; |              bool resultOK   =InitialSimboMLEnginesAsync(); | ||||||
|             Cameras.Add(do3ThinkCamera1); |             if (resultOK) | ||||||
|             Cameras.Add(do3ThinkCamera2); |             { | ||||||
|             do3ThinkCamera1.CameraConnect(); |                 //初始化失败 | ||||||
|             do3ThinkCamera2.CameraConnect(); |                // return; | ||||||
|             do3ThinkCamera1.OnHImageOutput += OnCameraHImageOutput; |             } | ||||||
|             do3ThinkCamera2.OnHImageOutput += OnCameraHImageOutput; |             //位置比较卡 | ||||||
|             var simbo1 = new SimboObjectDetection(); |              | ||||||
|             MLInit mLInit; |             sLDMotion.AxisSettings = new List<AxisSetting>(); | ||||||
|  |             AxisSetting axis1=new AxisSetting(); | ||||||
|  |             axis1.AxisIndex = 0; | ||||||
|  |             axis1.AxisName = "转盘1"; | ||||||
|  |             axis1.IsAxisEnabled = true; | ||||||
|  |             //axis1.AlarmLogic = AxisDirection.Positive; | ||||||
|  |             sLDMotion.IODefinitionCollection=new List<IODefinition>(); | ||||||
|  |             Motion(sLDMotion.IODefinitionCollection); | ||||||
|  |  | ||||||
|  |  | ||||||
|             mLInit = new MLInit($"D:\\PROJECTS\\MaodingTest1\\Vision\\cam1.onnx", "images", inferenceDevice, 640, 640); |  | ||||||
|  |             sLDMotion.SnapshotSettings = new List<SnapshotSetting>(); | ||||||
|  |             int[] cameraPositions = { 7613, 24161, 33608, 39702, 45701 }; | ||||||
|  |  | ||||||
|  |             for (int i = 0; i < 5; i++) | ||||||
|  |             { | ||||||
|  |                 sLDMotion.SnapshotSettings.Add(new SnapshotSetting | ||||||
|  |                 { | ||||||
|  |                     IsEnabled = true, | ||||||
|  |                     CameraIO = sLDMotion.IODefinitionCollection.FirstOrDefault(t => t.IOType == IOType.OUTPUT && t.IOIndex == i), | ||||||
|  |                     CameraPosition = cameraPositions[i], | ||||||
|  |                     StationNumber = 0 | ||||||
|  |                 }); | ||||||
|  |             } | ||||||
|  |  | ||||||
|  |  | ||||||
|             simbo1.Load(mLInit); |  | ||||||
|  |             sLDMotion.BlowSettings = new List<BlowSetting>(); | ||||||
|  |             int[] BlowPositions = { 61353, 68566 }; | ||||||
|  |  | ||||||
|  |             for (int i = 0; i < 2; i++) | ||||||
|  |             { | ||||||
|  |                 sLDMotion.BlowSettings.Add(new BlowSetting | ||||||
|  |                 { | ||||||
|  |                     IsEnabled = true, | ||||||
|  |                     BlowIO = sLDMotion.IODefinitionCollection.FirstOrDefault(t => t.IOType == IOType.OUTPUT && t.IOIndex == i), | ||||||
|  |                     BlowPosition = BlowPositions[i], | ||||||
|  |                     StationNumber = 0 | ||||||
|  |                 }); | ||||||
|  |             } | ||||||
|  |  | ||||||
|  |             //SnapshotSetting sna1 = new SnapshotSetting(); | ||||||
|  |             //sna1.IsEnabled = true; | ||||||
|  |             //sna1.CameraIO= sLDMotion.IODefinitionCollection.FirstOrDefault(t => t.IOType == IOType.OUTPUT && t.IOIndex == 0); | ||||||
|  |             //sna1.CameraPosition = 17000; | ||||||
|  |             //sna1.StationNumber = 0; | ||||||
|  |  | ||||||
|  |  | ||||||
|             Dectection.Add(det1.Id, simbo1); |  | ||||||
|  |  | ||||||
|             var simbo2 = new SimboObjectDetection(); |             // sLDMotion.SnapshotSettings.Add(sna1); | ||||||
|             MLInit mLInit2; |             sLDMotion.AxisSettings.Add(axis1); | ||||||
|  |             sLDMotion.Init(); | ||||||
|  |            // sLDMotion.Start(); | ||||||
|            |            | ||||||
|  |             //PLC.IP = "192.168.6.6"; | ||||||
|             mLInit2 = new MLInit($"D:\\PROJECTS\\MaodingTest1\\Vision\\cam2.onnx", "images", inferenceDevice, 640, 640); |             //PLC.Port = 502; | ||||||
|  |             //PLC.PLCConnect(); | ||||||
|  |             //PLC.OnNewPieces -= MainMotion_NewPieces; | ||||||
|             simbo2.Load(mLInit2); |             //PLC.OnNewPieces += MainMotion_NewPieces; | ||||||
|             |  | ||||||
|             Dectection.Add(det2.Id, simbo2); |  | ||||||
|  |  | ||||||
|             PLC.IP = "192.168.6.6"; |  | ||||||
|             PLC.Port = 502; |  | ||||||
|             PLC.PLCConnect(); |  | ||||||
|             PLC.OnNewPieces -= MainMotion_NewPieces; |  | ||||||
|             PLC.OnNewPieces += MainMotion_NewPieces; |  | ||||||
|             ProductBaseCount = 2; |             ProductBaseCount = 2; | ||||||
|             for (int i = 0; i < ProductBaseCount * ProductListMulti; i++) |             for (int i = 0; i < ProductBaseCount * ProductListMulti; i++) | ||||||
|             { |             { | ||||||
|                 ConcurrentDictionary<uint, ProductData> products = new ConcurrentDictionary<uint, ProductData>(); |                 ConcurrentDictionary<uint, ProductData> products = new ConcurrentDictionary<uint, ProductData>(); | ||||||
|                 _productLists.Add(products); |                 _productLists.Add(products); | ||||||
|             } |             } | ||||||
|             sraerttime=DateTime.Now; |            sLDMotion.AxisStop(); | ||||||
|  |            bool e=sLDMotion.CArdReset(); | ||||||
|  |             sLDMotion.JOGRun(10000, 100000); | ||||||
|  |           startTime =DateTime.Now; | ||||||
|         } |         } | ||||||
|  |         public void Motion(List<IODefinition> iODefinitions) | ||||||
|  |         { | ||||||
|  |             for (int i = 0; i < 16; i++) | ||||||
|  |             { | ||||||
|  |                 iODefinitions.Add(new IODefinition | ||||||
|  |                 { | ||||||
|  |                     IOType = IOType.INPUT, | ||||||
|  |                     IOIndex = i, | ||||||
|  |                     IODesc = $"入料传感器{i + 1}" | ||||||
|  |                 }); | ||||||
|  |             } | ||||||
|  |             for (int i = 0; i < 16; i++) | ||||||
|  |             { | ||||||
|  |                 iODefinitions.Add(new IODefinition | ||||||
|  |                 { | ||||||
|  |                     IOType = IOType.OUTPUT, | ||||||
|  |                     IOIndex = i, | ||||||
|  |                     IODesc = $"入料传感器{i + 1}" | ||||||
|  |                 }); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |  | ||||||
|         private uint PieceCount = 0; |         private uint PieceCount = 0; | ||||||
|         private List<ConcurrentDictionary<uint, ProductData>> _productLists = new List<ConcurrentDictionary<uint, ProductData>>(); |         private List<ConcurrentDictionary<uint, ProductData>> _productLists = new List<ConcurrentDictionary<uint, ProductData>>(); | ||||||
|         private int ProductListMulti = 2; |         private int ProductListMulti = 2; | ||||||
| @@ -457,11 +583,7 @@ namespace DHSoftware | |||||||
|         private int PieceNumberToIndex(uint pn) |         private int PieceNumberToIndex(uint pn) | ||||||
|         { |         { | ||||||
|             // 物料编号,取余 集合数量 |             // 物料编号,取余 集合数量 | ||||||
|             //int multiple = (int)(pn / ProductBaseCount) % 2; |  | ||||||
|             //int offset = (int)(pn % ProductBaseCount); |  | ||||||
|             //int ret = (ProductBaseCount * multiple) + offset; |  | ||||||
|             |             | ||||||
|             //int ret = (int)(pn % ProductBaseCount); |  | ||||||
|             int ret = (int)(pn % (ProductBaseCount * ProductListMulti)); |             int ret = (int)(pn % (ProductBaseCount * ProductListMulti)); | ||||||
|             return ret; |             return ret; | ||||||
|         } |         } | ||||||
| @@ -503,6 +625,302 @@ namespace DHSoftware | |||||||
|                //OnUpdateCT?.Invoke(objData, ctTime); |                //OnUpdateCT?.Invoke(objData, ctTime); | ||||||
|             }); |             }); | ||||||
|         } |         } | ||||||
|  |         /// <summary> | ||||||
|  |         /// 初始化深度学习工具 | ||||||
|  |         /// </summary> | ||||||
|  |         private bool InitialSimboMLEnginesAsync() | ||||||
|  |         { | ||||||
|  |             //深度学习 模型加载 | ||||||
|  |             var resultOK = MLLoadModel(); | ||||||
|  |            return resultOK; | ||||||
|  |         } | ||||||
|  |         /// <summary> | ||||||
|  |         /// 深度学习 模型加载 | ||||||
|  |         /// </summary> | ||||||
|  |         /// <returns></returns> | ||||||
|  |         private bool MLLoadModel() | ||||||
|  |         { | ||||||
|  |             bool resultOK = false; | ||||||
|  |             try | ||||||
|  |             { | ||||||
|  |                 SimboStationMLEngineList = new List<SimboStationMLEngineSet>(); | ||||||
|  |                 // _cameraRelatedDetectionDict = IConfig.DetectionConfigs.Select(t => t.ModelPath).Distinct().ToList(); | ||||||
|  |                DetectionConfigs.ForEach(dc => | ||||||
|  |                 //_cameraRelatedDetectionDict.ForEach(dc => | ||||||
|  |                 { | ||||||
|  |                     | ||||||
|  |                     if (dc.IsEnabled && !string.IsNullOrWhiteSpace(dc.ModelPath)) | ||||||
|  |                     { | ||||||
|  |                         if (dc.IsEnableGPU) | ||||||
|  |                         { | ||||||
|  |                             //if (IIConfig.IsLockGPU) | ||||||
|  |                             //{ | ||||||
|  |                                 //foreach (var validGPU in ValidGPUList2) | ||||||
|  |                                 //{ | ||||||
|  |                                 //    if (validGPU.DetectionIds.Contains(dc.Id)) | ||||||
|  |                                 //    { | ||||||
|  |                                         var engine = SingleMLLoadModel(dc, true, 0); | ||||||
|  |                                         SimboStationMLEngineList.Add(engine); | ||||||
|  |                                 //    } | ||||||
|  |                                 //} | ||||||
|  |                             //} | ||||||
|  |                             //else | ||||||
|  |                             //{ | ||||||
|  |                             //    foreach (var validGPU in ValidGPUList) | ||||||
|  |                             //    { | ||||||
|  |                             //        //var validGPU = ValidGPUList.FirstOrDefault(u => u.DetectionIds.Contains(dc.Id)); | ||||||
|  |                             //        if (validGPU.DetectionId == dc.Id) | ||||||
|  |                             //        { | ||||||
|  |                             //            var engine = SingleMLLoadModel(dc, true, validGPU.GPUNo); | ||||||
|  |                             //            SimboStationMLEngineList.Add(engine); | ||||||
|  |                             //        } | ||||||
|  |                             //    } | ||||||
|  |                             //} | ||||||
|  |  | ||||||
|  |                         } | ||||||
|  |                         else | ||||||
|  |                         { | ||||||
|  |                             //for (int i = 0; i < IConfig.CPUNums; i++) | ||||||
|  |                             for (int i = 0; i <1; i++) | ||||||
|  |                             { | ||||||
|  |                                 //var engine = SingleMLLoadModel(dc, false, i); | ||||||
|  |                                 var engine = SingleMLLoadModel(dc, false, i); | ||||||
|  |                                 SimboStationMLEngineList.Add(engine); | ||||||
|  |                             } | ||||||
|  |                         } | ||||||
|  |                     } | ||||||
|  |                 }); | ||||||
|  |                 resultOK = true; | ||||||
|  |             } | ||||||
|  |             catch (Exception ex) | ||||||
|  |             { | ||||||
|  |                // LogAsync(DateTime.Now, LogLevel.Exception, $"异常:模型并发加载异常:{ex.GetExceptionMessage()}"); | ||||||
|  |                 resultOK = false; | ||||||
|  |             } | ||||||
|  |  | ||||||
|  |             return resultOK; | ||||||
|  |         } | ||||||
|  |         /// <summary> | ||||||
|  |         /// 单个模型加载 | ||||||
|  |         /// </summary> | ||||||
|  |         /// <param name="dc"></param> | ||||||
|  |         /// <param name="gpuNum"></param> | ||||||
|  |         /// <returns></returns> | ||||||
|  |         private SimboStationMLEngineSet SingleMLLoadModel(DetectionConfig dc, bool isGPU, int coreInx) | ||||||
|  |         { | ||||||
|  |             SimboStationMLEngineSet mLEngineSet = new SimboStationMLEngineSet(); | ||||||
|  |             try | ||||||
|  |             { | ||||||
|  |                 mLEngineSet.IsUseGPU = isGPU; | ||||||
|  |                 if (isGPU) | ||||||
|  |                 { | ||||||
|  |                     mLEngineSet.GPUNo = coreInx; | ||||||
|  |                 } | ||||||
|  |                 else | ||||||
|  |                 { | ||||||
|  |                     mLEngineSet.CPUNo = coreInx; | ||||||
|  |                 } | ||||||
|  |                 mLEngineSet.DetectionId = dc.Id; | ||||||
|  |                 mLEngineSet.DetectionName = dc.Name; | ||||||
|  |  | ||||||
|  |                 if (!string.IsNullOrWhiteSpace(dc.ModelPath)) | ||||||
|  |                 { | ||||||
|  |                     // 根据算法类型创建不同的实例 | ||||||
|  |                     switch (dc.ModelType) | ||||||
|  |                     { | ||||||
|  |                         case MLModelType.ImageClassification: | ||||||
|  |                             break; | ||||||
|  |                         case MLModelType.ObjectDetection: | ||||||
|  |                             mLEngineSet.StationMLEngine = new SimboObjectDetection(); | ||||||
|  |                             break; | ||||||
|  |                         case MLModelType.SemanticSegmentation: | ||||||
|  |  | ||||||
|  |                             break; | ||||||
|  |                         case MLModelType.InstanceSegmentation: | ||||||
|  |                             mLEngineSet.StationMLEngine = new SimboInstanceSegmentation(); | ||||||
|  |                             break; | ||||||
|  |                         case MLModelType.ObjectGPUDetection: | ||||||
|  |                             mLEngineSet.StationMLEngine = new SimboDetection(); | ||||||
|  |                             break; | ||||||
|  |                         default: | ||||||
|  |                             break; | ||||||
|  |                     } | ||||||
|  |                     MLInit mLInit; | ||||||
|  |                     string inferenceDevice = "CPU"; | ||||||
|  |                     if (dc.IsEnableGPU) | ||||||
|  |                     { | ||||||
|  |                         inferenceDevice = "GPU"; | ||||||
|  |                         mLInit = new MLInit(dc.ModelPath, isGPU, coreInx, dc.ModelconfThreshold); | ||||||
|  |                     } | ||||||
|  |                     else | ||||||
|  |                     { | ||||||
|  |                         mLInit = new MLInit(dc.ModelPath, "images", inferenceDevice, (int)dc.ModelWidth, (int)dc.ModelHeight); | ||||||
|  |  | ||||||
|  |                     } | ||||||
|  |  | ||||||
|  |                     bool isSuccess = mLEngineSet.StationMLEngine.Load(mLInit); | ||||||
|  |                     if (!isSuccess) | ||||||
|  |                     { | ||||||
|  |                        // throw new ProcessException("异常:模型加载异常", null); | ||||||
|  |                     } | ||||||
|  |                     //LogAsync(DateTime.Now, LogLevel.Information, $"模型加载成功;是否GPU:{isGPU} CoreInx:{coreInx} - {dc.Name}" + $" {dc.ModelType.GetEnumDescription()}:{dc.ModelPath}"); | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |             catch (Exception ex) | ||||||
|  |             { | ||||||
|  |                 //throw new ProcessException($"异常:是否GPU:{isGPU} CoreInx:{coreInx} - {dc.Name}模型加载异常:{ex.GetExceptionMessage()}"); | ||||||
|  |             } | ||||||
|  |             return mLEngineSet; | ||||||
|  |         } | ||||||
|  |         private void InitialHalconTools() | ||||||
|  |         { | ||||||
|  |             HOperatorSet.SetSystem("parallelize_operators", "true"); | ||||||
|  |             HOperatorSet.SetSystem("reentrant", "true"); | ||||||
|  |             HOperatorSet.SetSystem("global_mem_cache", "exclusive"); | ||||||
|  |  | ||||||
|  |             HalconToolDict = new Dictionary<string, HDevEngineTool>(); | ||||||
|  |  | ||||||
|  |             DetectionConfigs.ForEach(c => | ||||||
|  |             { | ||||||
|  |                 if (!c.IsEnabled) | ||||||
|  |                     return; | ||||||
|  |  | ||||||
|  |                 if(c.HalconAlgorithemPath_Pre!=null) | ||||||
|  |                     LoadHalconTool(c.HalconAlgorithemPath_Pre); | ||||||
|  |                 | ||||||
|  |             }); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         private void LoadHalconTool(string path) | ||||||
|  |         { | ||||||
|  |             if (!HalconToolDict.ContainsKey(path)) | ||||||
|  |             { | ||||||
|  |                 | ||||||
|  |  | ||||||
|  |                 string algorithemPath = path; | ||||||
|  |  | ||||||
|  |                 if (string.IsNullOrWhiteSpace(algorithemPath)) | ||||||
|  |                     return; | ||||||
|  |  | ||||||
|  |                 string directoryPath = Path.GetDirectoryName(algorithemPath); | ||||||
|  |                 string fileName = Path.GetFileNameWithoutExtension(algorithemPath); | ||||||
|  |  | ||||||
|  |                 HDevEngineTool tool = new HDevEngineTool(directoryPath); | ||||||
|  |                 tool.LoadProcedure(fileName); | ||||||
|  |  | ||||||
|  |                 HalconToolDict[path] = tool; | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         /// <summary> | ||||||
|  |         /// 预处理 | ||||||
|  |         /// </summary> | ||||||
|  |         /// <param name="detectConfig"></param> | ||||||
|  |         /// <param name="detectResult"></param> | ||||||
|  |         public void PreTreated(DetectionConfig detectConfig, DetectStationResult detectResult,Mat MhImage) | ||||||
|  |         { | ||||||
|  |             try | ||||||
|  |             { | ||||||
|  |                 // detectResult.VisionImageSet.DetectionOriginImage = detectResult.VisionImageSet.HImage.ConvertHImageToBitmap(); | ||||||
|  |                 //detectResult.VisionImageSet.PreTreatedBitmap = detectResult.VisionImageSet.HImage.ConvertHImageToBitmap(); | ||||||
|  |                 //detectResult.VisionImageSet.DetectionResultImage = detectResult.VisionImageSet.PreTreatedBitmap?.CopyBitmap(); | ||||||
|  |                 if (!string.IsNullOrWhiteSpace(detectConfig.HalconAlgorithemPath_Pre)) | ||||||
|  |                 { | ||||||
|  |                     HObject obj = OpenCVHelper.MatToHImage(MhImage); | ||||||
|  |                     HImage hImage = HalconHelper.ConvertHObjectToHImage(obj); | ||||||
|  |                     string toolKey =  detectConfig.HalconAlgorithemPath_Pre; | ||||||
|  |                     if (!HalconToolDict.ContainsKey(toolKey)) | ||||||
|  |                     { | ||||||
|  |                        // LogAsync(DateTime.Now, LogLevel.Exception, $"{detectConfig.Name}未获取预处理算法"); | ||||||
|  |                         return; | ||||||
|  |                     } | ||||||
|  |                     //Mean_Thre Deviation_Thre  Mean_standard Deviation_standard | ||||||
|  |                     var tool = HalconToolDict[toolKey]; | ||||||
|  |  | ||||||
|  |                     ////tool.InputTupleDic["Mean_Thre"] = 123; | ||||||
|  |                     for (int i = 0; i < detectConfig.PreTreatParams.Count; i++) | ||||||
|  |                     { | ||||||
|  |                         var param = detectConfig.PreTreatParams[i]; | ||||||
|  |                         tool.InputTupleDic[param.Name] = double.Parse(param.Value); | ||||||
|  |                     } | ||||||
|  |  | ||||||
|  |                     // tool.InputTupleDic["fCricularity"] = 200; | ||||||
|  |  | ||||||
|  |                     tool.InputImageDic["INPUT_Image"] = hImage; | ||||||
|  |  | ||||||
|  |  | ||||||
|  |                     if (!tool.RunProcedure(out string errorMsg, out _)) | ||||||
|  |                     { | ||||||
|  |                       //  detectResult.PreTreatedFlag = false; | ||||||
|  |                         | ||||||
|  |                         detectResult.IsPreTreatDone = false; | ||||||
|  |  | ||||||
|  |                        | ||||||
|  |                         return; | ||||||
|  |                     } | ||||||
|  |  | ||||||
|  |                     var preTreatRet = tool.GetResultTuple("OUTPUT_Flag").I; | ||||||
|  |  | ||||||
|  |                     //var fRCricularity = tool.GetResultTuple("fRCricularity"); | ||||||
|  |  | ||||||
|  |  | ||||||
|  |                     // detectResult.IsPreTreatDone = detectResult.VisionImageSet.PreTreatedFlag = preTreatRet == 1; | ||||||
|  |                     //detectResult.IsPreTreatDone = detectResult.VisionImageSet.PreTreatedFlag = true; | ||||||
|  |                     //  detectResult.VisionImageSet.PreTreatedTime = DateTime.Now; | ||||||
|  |  | ||||||
|  |                     for (int i = 0; i < detectConfig.OUTPreTreatParams.Count; i++) | ||||||
|  |                     { | ||||||
|  |                         var param = detectConfig.OUTPreTreatParams[i]; | ||||||
|  |                         tool.InputTupleDic[param.Name] = double.Parse(param.Value); | ||||||
|  |                     } | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  |                     // 2023/10/16 新增预处理结果反馈,如果预处理结果为NG,直接返回 | ||||||
|  |                     if (preTreatRet != 0) | ||||||
|  |                     { | ||||||
|  |                         detectResult.ResultState = ResultState.DetectNG; | ||||||
|  |  | ||||||
|  |                         detectResult.IsPreTreatNG = true; | ||||||
|  |                        | ||||||
|  |  | ||||||
|  |  | ||||||
|  |                         // if (detectResult.VisionImageSet.PreTreatedFlag) | ||||||
|  |                         { | ||||||
|  |                             //detectResult.VisionImageSet.MLImage = tool.GetResultObject("OUTPUT_PreTreatedImage"); | ||||||
|  |                             //DetectionResultImage | ||||||
|  |                            // detectResult.VisionImageSet.DetectionResultImage = detectResult.VisionImageSet.MLImage.ConvertHImageToBitmap(); | ||||||
|  |  | ||||||
|  |                         } | ||||||
|  |  | ||||||
|  |                     } | ||||||
|  |                     else | ||||||
|  |                     { | ||||||
|  |                        // detectResult.VisionImageSet.DetectionResultImage = detectResult.VisionImageSet.MLImage.ConvertHImageToBitmap(); | ||||||
|  |  | ||||||
|  |                     } | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |             catch (Exception ex) | ||||||
|  |             { | ||||||
|  |                  | ||||||
|  |             } | ||||||
|  |             finally | ||||||
|  |             { | ||||||
|  |                 //detectResult.VisionImageSet.HImage?.Dispose(); | ||||||
|  |                 //detectResult.VisionImageSet.HImage = null; | ||||||
|  |                // MhImage?.Dispose(); | ||||||
|  |                 //MhImage = null; | ||||||
|  |             } | ||||||
|  |              | ||||||
|  |         } | ||||||
|  |         /// <summary> | ||||||
|  |         /// 相机回调 | ||||||
|  |         /// </summary> | ||||||
|  |         /// <param name="dt"></param> | ||||||
|  |         /// <param name="camera"></param> | ||||||
|  |         /// <param name="imageSet"></param> | ||||||
|         private void OnCameraHImageOutput(DateTime dt, CameraBase camera, Mat imageSet) |         private void OnCameraHImageOutput(DateTime dt, CameraBase camera, Mat imageSet) | ||||||
|         { |         { | ||||||
|             // 获取该相机的拍照计数 |             // 获取该相机的拍照计数 | ||||||
| @@ -572,17 +990,16 @@ namespace DHSoftware | |||||||
|                         for (int i = 0; i < detectionDict.Count; i++) |                         for (int i = 0; i < detectionDict.Count; i++) | ||||||
|                         { |                         { | ||||||
|                             string detectionId = detectionDict[i]; |                             string detectionId = detectionDict[i]; | ||||||
|                             try |  | ||||||
|                             { |  | ||||||
|                             DetectionConfig detectConfig = null; |                             DetectionConfig detectConfig = null; | ||||||
|                             //找到对应的配置 |                             //找到对应的配置 | ||||||
|                             if (!string.IsNullOrWhiteSpace(detectionId)) |                             if (!string.IsNullOrWhiteSpace(detectionId)) | ||||||
|                             { |                             { | ||||||
|                                     detectConfig = detectionList.FirstOrDefault(u => u.Id == detectionId); |                                 detectConfig = DetectionConfigs.FirstOrDefault(u => u.Id == detectionId); | ||||||
|                             } |                             } | ||||||
|                             else |                             else | ||||||
|                             { |                             { | ||||||
|                                     detectConfig = detectionList.FirstOrDefault(u => u.CameraSourceId == camera.CameraName); |                                 detectConfig = DetectionConfigs.FirstOrDefault(u => u.CameraSourceId == camera.CameraName); | ||||||
|                             } |                             } | ||||||
|  |  | ||||||
|                             if (detectConfig == null) |                             if (detectConfig == null) | ||||||
| @@ -595,36 +1012,123 @@ namespace DHSoftware | |||||||
|                             // 1. 预处理 |                             // 1. 预处理 | ||||||
|                             using (Mat inferenceImage = localImageSet.Clone()) // 仅在此处克隆,确保推理过程中 Mat 有独立副本 |                             using (Mat inferenceImage = localImageSet.Clone()) // 仅在此处克隆,确保推理过程中 Mat 有独立副本 | ||||||
|                             { |                             { | ||||||
|  |                                 DetectStationResult detectResult = new DetectStationResult(); | ||||||
|                                 #region 1.预处理 |                                 #region 1.预处理 | ||||||
|  |  | ||||||
|  |                                 using (Mat PreTMat = inferenceImage.Clone()) | ||||||
|  |                                 { | ||||||
|  |                                     PreTreated(detectConfig, detectResult, PreTMat); | ||||||
|  |                                 } | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|                                 #endregion |                                 #endregion | ||||||
|  |                                 if (detectResult.IsPreTreatNG) | ||||||
|  |                                 { | ||||||
|  |                                     detectResult.ResultState = ResultState.DetectNG; | ||||||
|  |                                     detectResult.IsPreTreatDone = true; | ||||||
|  |                                     detectResult.IsMLDetectDone = false; | ||||||
|  |  | ||||||
|  |                                 } | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  |                                 if (!string.IsNullOrWhiteSpace(detectConfig.ModelPath) && detectConfig.IsEnabled) | ||||||
|  |                                 { | ||||||
|  |  | ||||||
|  |  | ||||||
|  |                                     SimboStationMLEngineSet mlSet = null; | ||||||
|  |                                     mlSet = SimboStationMLEngineList.FirstOrDefault(t => t.DetectionId == detectConfig.Id); | ||||||
|  |                                     if (mlSet == null) | ||||||
|  |                                     { | ||||||
|  |                                         // LogAsync(DateTime.Now, LogLevel.Exception, $"异常:{detectConfig.Name}未能获取对应配置的模型检测工具"); | ||||||
|  |                                         detectResult.IsMLDetectDone = false; | ||||||
|  |  | ||||||
|  |                                         //HandleDetectDone(detectResult, detectConfig); | ||||||
|  |                                         return; | ||||||
|  |                                     } | ||||||
|  |  | ||||||
|                                     #region 2.深度学习推理  |                                     #region 2.深度学习推理  | ||||||
|  |                                     //LogAsync(DateTime.Now, LogLevel.Information, $"{detectConfig.Name} 产品{detectResult.TempPid} 模型检测执行"); | ||||||
|  |  | ||||||
|  |                                     if (!string.IsNullOrWhiteSpace(detectConfig.ModelPath)) | ||||||
|  |                                     { | ||||||
|  |                                         Stopwatch mlWatch = new Stopwatch(); | ||||||
|                                         var req = new MLRequest(); |                                         var req = new MLRequest(); | ||||||
|  |                                         //之前的检测图片都是相机存储成HImage | ||||||
|  |  | ||||||
|                                     req.mImage = inferenceImage; |  | ||||||
|  |  | ||||||
|                                     req.ResizeWidth = 640; |                                         req.ResizeWidth = (int)detectConfig.ModelWidth; | ||||||
|                                     req.ResizeHeight = 640; |                                         req.ResizeHeight = (int)detectConfig.ModelHeight; | ||||||
|                                     req.confThreshold = 0.5f; |                                         // req.LabelNames = detectConfig.GetLabelNames(); | ||||||
|  |                                         // req.Score = IIConfig.Score; | ||||||
|  |  | ||||||
|  |  | ||||||
|  |                                         req.in_lable_path = detectConfig.in_lable_path; | ||||||
|  |  | ||||||
|  |                                         req.confThreshold = detectConfig.ModelconfThreshold; | ||||||
|                                         req.iouThreshold = 0.3f; |                                         req.iouThreshold = 0.3f; | ||||||
|                                     req.out_node_name = "output0"; |                                         req.segmentWidth = 320; | ||||||
|                                     req.in_lable_path = "D:\\PROJECTS\\MaodingTest1\\Vision\\cam1.txt"; |  | ||||||
|  |  | ||||||
|                                     Stopwatch sw = Stopwatch.StartNew(); |                                         switch (detectConfig.ModelType) | ||||||
|                                     var result = Dectection[detectionId].RunInference(req); |                                         { | ||||||
|                                     sw.Stop(); |                                             case MLModelType.ImageClassification: | ||||||
|  |                                                 break; | ||||||
|  |                                             case MLModelType.ObjectDetection: | ||||||
|  |  | ||||||
|  |                                                 break; | ||||||
|  |                                             case MLModelType.SemanticSegmentation: | ||||||
|  |                                                 break; | ||||||
|  |                                             case MLModelType.InstanceSegmentation: | ||||||
|  |                                                 break; | ||||||
|  |                                             case MLModelType.ObjectGPUDetection: | ||||||
|  |  | ||||||
|  |                                                 break; | ||||||
|  |                                             default: | ||||||
|  |                                                 break; | ||||||
|  |                                         } | ||||||
|  |  | ||||||
|  |                                         //  LogAsync(DateTime.Now, LogLevel.Information, $"{detectConfig.Name} 产品{detectResult.TempPid} RunInference BEGIN"); | ||||||
|  |                                         mlWatch.Start(); | ||||||
|  |                                         //20230802改成多线程推理 RunInferenceFixed | ||||||
|  |  | ||||||
|  |                                         var result = mlSet.StationMLEngine.RunInference(req); | ||||||
|  |                                         // var result = mlSet.StationMLEngine.RunInferenceFixed(req); | ||||||
|  |                                         mlWatch.Stop(); | ||||||
|  |                                         // LogAsync(DateTime.Now, LogLevel.Information, $"{detectConfig.Name} 产品{detectResult.TempPid} RunInference END"); | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  |                                         //            var req = new MLRequest(); | ||||||
|  |  | ||||||
|  |                                         //req.mImage = inferenceImage; | ||||||
|  |  | ||||||
|  |                                         //req.ResizeWidth = detectConfig.ModelWidth; | ||||||
|  |                                         //req.ResizeHeight = detectConfig.ModelHeight; | ||||||
|  |                                         //req.confThreshold = detectConfig.ModelconfThreshold; | ||||||
|  |                                         //req.iouThreshold = 0.3f; | ||||||
|  |                                         //req.out_node_name = "output0"; | ||||||
|  |                                         //req.in_lable_path = detectConfig.in_lable_path; | ||||||
|  |  | ||||||
|  |                                         //Stopwatch sw = Stopwatch.StartNew(); | ||||||
|  |                                         //var result =   Dectection[detectionId].RunInference(req); | ||||||
|  |                                         //sw.Stop(); | ||||||
|                                         //LogAsync(DateTime.Now, LogLevel.Information, $"{camera.Name} 推理进度1.1,产品{productNumber},耗时{sw.ElapsedMilliseconds}ms"); |                                         //LogAsync(DateTime.Now, LogLevel.Information, $"{camera.Name} 推理进度1.1,产品{productNumber},耗时{sw.ElapsedMilliseconds}ms"); | ||||||
|                                     #endregion |                                         | ||||||
|                                         this.BeginInvoke(new MethodInvoker(delegate () |                                         this.BeginInvoke(new MethodInvoker(delegate () | ||||||
|                                         { |                                         { | ||||||
|                                             pictureBox1.Image?.Dispose(); // 释放旧图像 |                                             pictureBox1.Image?.Dispose(); // 释放旧图像 | ||||||
|                                             pictureBox1.Image = result.ResultMap; |                                             pictureBox1.Image = result.ResultMap; | ||||||
|                                         richTextBox1.AppendText($"推理成功 {productNumber}, {result.IsSuccess} 耗时 {sw.ElapsedMilliseconds}ms\n"); |                                             richTextBox1.AppendText($"推理成功 {productNumber}, {result.IsSuccess} 耗时 {mlWatch.ElapsedMilliseconds}ms\n"); | ||||||
|                                         })); |                                         })); | ||||||
|                                         req.mImage.Dispose(); |                                         req.mImage.Dispose(); | ||||||
| #if true |  | ||||||
|  |  | ||||||
|                                     #region 3.后处理 |  | ||||||
|                                     DetectStationResult detectResult = new DetectStationResult(); |  | ||||||
|  |  | ||||||
|                                         if (result == null || (result != null && !result.IsSuccess)) |                                         if (result == null || (result != null && !result.IsSuccess)) | ||||||
|                                         { |                                         { | ||||||
|                                             detectResult.IsMLDetectDone = false; |                                             detectResult.IsMLDetectDone = false; | ||||||
| @@ -640,8 +1144,11 @@ namespace DHSoftware | |||||||
|                                                 detectResult.IsMLDetectDone = false; |                                                 detectResult.IsMLDetectDone = false; | ||||||
|                                             } |                                             } | ||||||
|                                         } |                                         } | ||||||
|  |                                     } | ||||||
|                                     #endregion |                                     #endregion | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|                                     #region 3.后处理 |                                     #region 3.后处理 | ||||||
|                                     #endregion |                                     #endregion | ||||||
|                                     //根据那些得分大于阈值的推理结果,判断产品是否成功 |                                     //根据那些得分大于阈值的推理结果,判断产品是否成功 | ||||||
| @@ -721,28 +1228,24 @@ namespace DHSoftware | |||||||
|                                .FirstOrDefault()?.Key ?? ResultState.OK; |                                .FirstOrDefault()?.Key ?? ResultState.OK; | ||||||
|                                     detectResult.ResultLabel = detectResult.ResultLabel; |                                     detectResult.ResultLabel = detectResult.ResultLabel; | ||||||
|                                     detectResult.ResultLabelCategoryId = detectResult.ResultLabel;//TODO:设置优先级 |                                     detectResult.ResultLabelCategoryId = detectResult.ResultLabel;//TODO:设置优先级 | ||||||
|  |  | ||||||
|                                     #endregion |                                     #endregion | ||||||
|  |  | ||||||
|                                     resultStates.Add(detectResult.ResultState); |                                     resultStates.Add(detectResult.ResultState); | ||||||
|  |  | ||||||
|                                     product.ResultCollection.Add(detectResult); |                                     product.ResultCollection.Add(detectResult); | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
| #endif |  | ||||||
|  |  | ||||||
|  |  | ||||||
|                                 } |                                 } | ||||||
|  |  | ||||||
|                             } |  | ||||||
|                             catch (Exception ex) |  | ||||||
|                             { |  | ||||||
|                                 //  LogAsync(DateTime.Now, LogLevel.Information, $"{camera.Name} 推理异常,物料编号:{productNumber},检测项:{d}, {ex.GetExceptionMessage}"); |  | ||||||
|                             } |  | ||||||
|                             } |                             } | ||||||
|  |  | ||||||
|  |  | ||||||
|  |                         } | ||||||
|  |  | ||||||
|                             product.InferenceOne(() => |                             product.InferenceOne(() => | ||||||
|                             { |                             { | ||||||
| @@ -766,7 +1269,7 @@ namespace DHSoftware | |||||||
|  |  | ||||||
|                                 int currentScrollPosition = richTextBox1.GetPositionFromCharIndex(richTextBox1.TextLength).Y; |                                 int currentScrollPosition = richTextBox1.GetPositionFromCharIndex(richTextBox1.TextLength).Y; | ||||||
|  |  | ||||||
|                             richTextBox1.AppendText($"统计结果成功,{productNumber}吹气!\n"); |                                 richTextBox1.AppendText($"统计结果成功,{productNumber}  吹气!\n"); | ||||||
|  |  | ||||||
|                                 // 设置回原来的滚动位置 |                                 // 设置回原来的滚动位置 | ||||||
|                                 richTextBox1.SelectionStart = richTextBox1.TextLength; |                                 richTextBox1.SelectionStart = richTextBox1.TextLength; | ||||||
| @@ -803,7 +1306,7 @@ namespace DHSoftware | |||||||
|                             } |                             } | ||||||
|                             if (temp == null) |                             if (temp == null) | ||||||
|                             { |                             { | ||||||
|                             string logStr = $"{DateTime.Now}产品{productNumber}出列失败:true,"+  |                                 string logStr = $"{DateTime.Now}产品{productNumber}出列失败:true," + | ||||||
|                                    $"当前队列产品数量:{tmpDic.Count}"; |                                    $"当前队列产品数量:{tmpDic.Count}"; | ||||||
|                                 this.BeginInvoke(new MethodInvoker(delegate () |                                 this.BeginInvoke(new MethodInvoker(delegate () | ||||||
|                                 { |                                 { | ||||||
| @@ -837,7 +1340,7 @@ namespace DHSoftware | |||||||
|                                     })); |                                     })); | ||||||
|                                     //重新生成实例 销毁之前的实例 |                                     //重新生成实例 销毁之前的实例 | ||||||
|                                     var saveData = temp.GetProductData(); |                                     var saveData = temp.GetProductData(); | ||||||
|                                 using(StreamWriter sw=new StreamWriter("D://123log.txt",true,Encoding.UTF8)) |                                     using (StreamWriter sw = new StreamWriter("D://123log.txt", true, Encoding.UTF8)) | ||||||
|                                     { |                                     { | ||||||
|                                         sw.WriteLine(logStr); |                                         sw.WriteLine(logStr); | ||||||
|                                     } |                                     } | ||||||
| @@ -863,6 +1366,7 @@ namespace DHSoftware | |||||||
|                             product?.Dispose(); |                             product?.Dispose(); | ||||||
|                         } |                         } | ||||||
|                     } |                     } | ||||||
|  |  | ||||||
|                 }); |                 }); | ||||||
|         } |         } | ||||||
|         public void SetResult() |         public void SetResult() | ||||||
| @@ -895,11 +1399,12 @@ namespace DHSoftware | |||||||
|             // Add the code for the "停止" button click here |             // Add the code for the "停止" button click here | ||||||
|           PLC.TurntableStop(); |           PLC.TurntableStop(); | ||||||
|             CurrentMachine = true; |             CurrentMachine = true; | ||||||
|  |             sLDMotion.Stop(); | ||||||
|         } |         } | ||||||
|         public int UPH=0; |         public int UPH=0; | ||||||
|         public void CalculateOEE() |         public void CalculateOEE() | ||||||
|         { |         { | ||||||
|             TimeSpan timeSpan = DateTime.Now - sraerttime; |             TimeSpan timeSpan = DateTime.Now - startTime; | ||||||
|  |  | ||||||
|                 UPH = (int)(ProductNum_Total / timeSpan.TotalHours) + 100; |                 UPH = (int)(ProductNum_Total / timeSpan.TotalHours) + 100; | ||||||
|             //UPM = (int)UPH / 60; |             //UPM = (int)UPH / 60; | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user