using AntdUI; using AntdUI.Svg; using DH.Commons.Enums; using DH.Devices.Camera; using DH.Devices.Motion; using DH.Devices.PLC; using DH.Devices.Vision; using DHSoftware.Languages; using DHSoftware.Models; using DHSoftware.Utils; using DVPCameraType; using HalconDotNet; using Microsoft.Win32; using OpenCvSharp; using System; using System.CodeDom; using System.Collections.Concurrent; using System.Collections.Generic; using System.Diagnostics; using System.Drawing; using System.Linq; using System.Runtime.InteropServices; using System.Text; using System.Threading; using System.Threading.Tasks; using System.Windows.Forms; using XKRS.Common.Model; using static AntdUI.Math3D; using Camera = DHSoftware.Models.Camera; namespace DHSoftware { public partial class MainWindow : AntdUI.Window { private UserControl currControl; private bool isUpdatingTabs = false;//用于阻止Tabs更新 private bool isLight = true; // 定义一个语言切换事件 public event EventHandler LanguageChanged; private System.Windows.Forms.Timer refreshTimer; private int testCounter = 1; Dictionary> _cameraRelatedDetectionDict = null; public MainWindow() { InitializeComponent(); refreshTimer = new System.Windows.Forms.Timer(); refreshTimer.Interval = 1000; // 1秒间隔 refreshTimer.Tick += RefreshTimer_Tick; //refreshTimer.Start(); //初始化数据 InitData(); //绑定事件 BindEventHandler(); tabImgDisplay.Pages.Clear(); List Cameras = new List { new Camera { DeviceName = "Cam1", Alias = "相机1", ImagePath = @"D:\1.jpeg" }, new Camera { DeviceName = "Cam2", Alias = "相机2", ImagePath = @"D:\2.jpeg" }, new Camera { DeviceName = "Cam3", Alias = "相机3", ImagePath = @"D:\3.jpeg" }, new Camera { DeviceName = "Cam4", Alias = "相机4", ImagePath = @"D:\4.jpeg" }, new Camera { DeviceName = "Cam5", Alias = "相机5", ImagePath = @"D:\5.jpeg" } }; if (Cameras.Count > 0) { tabImgDisplay.Controls.Clear(); foreach (var cam in Cameras) { AntdUI.TabPage tabPage = new AntdUI.TabPage(); tabPage.Name = $"tab{cam.DeviceName}"; tabPage.Text = cam.Alias; //ImgDisplayControl imgDisplayControl = new ImgDisplayControl(); //imgDisplayControl.Name = $"img{cam.DeviceName}"; //imgDisplayControl.Dock = DockStyle.Fill; //tabPage.Controls.Add(imgDisplayControl); PictureBox pictureBox = new PictureBox(); pictureBox.Name = $"pic{cam.DeviceName}"; pictureBox.Dock = DockStyle.Fill; pictureBox.SizeMode = PictureBoxSizeMode.Zoom; tabPage.Controls.Add(pictureBox); tabImgDisplay.Pages.Add(tabPage); } } } private void RefreshTimer_Tick(object sender, EventArgs e) { // 获取相机1的控件(通过控件名称查找) var targetControl = FindControlRecursive(tabImgDisplay, "picCam1") as PictureBox; if (targetControl != null) { // 生成测试路径(示例路径) string testPath = $@"D:\{testCounter}.png"; // 循环1-5的图片 testCounter++; // 加载并显示图片 targetControl.Image = Image.FromFile(testPath); if (testCounter == 5) { testCounter = 1; } targetControl.Parent.Invalidate(); } } // 递归查找控件的方法 private Control FindControlRecursive(Control parent, string name) { if (parent.Name == name) return parent; foreach (Control child in parent.Controls) { var found = FindControlRecursive(child, name); if (found != null) return found; } return null; } // 触发事件 protected virtual void OnLanguageChanged(EventArgs e) { LanguageChanged?.Invoke(this, e); } private void InitData() { //根据系统亮暗初始化一次 isLight = ThemeHelper.IsLightMode(); button_color.Toggle = !isLight; ThemeHelper.SetColorMode(this, isLight); //初始化消息弹出位置 Config.ShowInWindow = true; } private void BindEventHandler() { buttonSZ.Click += ButtonSZ_Click; button_color.Click += Button_color_Click; //监听系统深浅色变化 SystemEvents.UserPreferenceChanged += SystemEvents_UserPreferenceChanged; } private void SystemEvents_UserPreferenceChanged(object sender, UserPreferenceChangedEventArgs e) { if (e.Category == UserPreferenceCategory.General) { isLight = ThemeHelper.IsLightMode(); button_color.Toggle = !isLight; ThemeHelper.SetColorMode(this, isLight); } } private void Button_color_Click(object sender, EventArgs e) { isLight = !isLight; //这里使用了Toggle属性切换图标 button_color.Toggle = !isLight; ThemeHelper.SetColorMode(this, isLight); } private void ButtonSZ_Click(object sender, EventArgs e) { } public List HKCameras { get; } = new List(); public List Cameras { get; } = new List(); public Dictionary Dectection { get; } = new Dictionary(); public XinJEPLCTcpNet PLC { get; } = new XinJEPLCTcpNet(); SLDMotion sLDMotion = new SLDMotion(); private void MainWindow_Load(object sender, EventArgs e) { } private void MainWindow_FormClosed(object sender, FormClosedEventArgs e) { foreach (var camera in Cameras) { camera.CameraDisConnect(); } foreach (var camera in HKCameras) { camera.CameraDisConnect(); } PLC.PLCDisConnect(); } private void segmented1_SelectIndexChanged(object sender, EventArgs e) { // Get the index of the selected item int selectedIndex = segmented1.SelectIndex; // Handle each button based on its index switch (selectedIndex) { case 0: // "启动" (Start) HandleStartButton(); break; case 1: // "停止" (Stop) HandleStopButton(); break; case 2: // "复位" (Reset) HandleResetButton(); break; case 3: // "设置" (Settings) HandleSettingsButton(); break; case 4: // "登录" (Login) HandleLoginButton(); break; default: break; } } public bool CurrentMachine = false; public volatile int ProductNum_Total = 0; public volatile int ProductNum_OK = 0; private readonly object _cameraSummaryLock = new object(); List DetectionConfigs = new List(); List SimboStationMLEngineList = new List(); Dictionary HalconToolDict = new Dictionary(); public List RecongnitionLabelList { get; set; } = new List(); public DateTime startTime; private void HandleStartButton() { CurrentMachine = true; //[Category("深度学习检测配置")] //[DisplayName("检测标签定义集合")] //[Description("定义检测标签的集合,例如:Seg/Detection模式:断裂、油污、划伤...;Class模式:ok、ng、上面、下面、套环、正常...")] //[TypeConverter(typeof(CollectionCountConvert))] //[Editor(typeof(ComplexCollectionEditor), typeof(UITypeEditor))] RecongnitionLabel recongnition = new RecongnitionLabel { LabelName = "youwu", LabelDescription = "油污", LabelCategory = "A_NG" }; RecongnitionLabel recongnition2 = new RecongnitionLabel { LabelName = "youwu", LabelDescription = "油污", LabelCategory = "A_NG" }; RecongnitionLabel recongnition3 = new RecongnitionLabel { LabelName = "youwu", LabelDescription = "油污", LabelCategory = "A_NG" }; RecongnitionLabelList.Add(recongnition); RecongnitionLabelList.Add(recongnition2); RecongnitionLabelList.Add(recongnition3); var det1 = new DetectionConfig("相机1", MLModelType.ObjectDetection, @"D:\PROJECTS\X015\Vision\Cam1.onnx", false, "Cam1"); var det2 = new DetectionConfig("相机2", MLModelType.ObjectDetection, @"D:\PROJECTS\X015\Vision\Cam2.onnx", false, "Cam2"); var det3 = new DetectionConfig("相机3", MLModelType.ObjectDetection, @"D:\PROJECTS\X015\Vision\Cam3.onnx", false, "Cam3"); 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 CameraCollects = new List(); CameraCollects.Add(new RelatedCamera("Cam1")); List CameraCollects2 = new List(); CameraCollects2.Add(new RelatedCamera("Cam2")); List CameraCollects3 = new List(); CameraCollects3.Add(new RelatedCamera("Cam3")); List CameraCollects4 = new List(); CameraCollects4.Add(new RelatedCamera("Cam4")); List CameraCollects5 = new List(); CameraCollects5.Add(new RelatedCamera("Cam5")); List CameraCollects6 = new List(); CameraCollects6.Add(new RelatedCamera("Cam6")); List CameraCollects7 = new List(); CameraCollects7.Add(new RelatedCamera("Cam7")); List CameraCollects8 = new List(); CameraCollects8.Add(new RelatedCamera("Cam8")); float Conf = 0.5f; det1.CameraCollects = CameraCollects; det1.ModelconfThreshold = Conf; det1.ModelWidth = 640; det1.ModelHeight = 640; det1.in_lable_path = "D:\\PROJECTS\\X015\\Vision\\Cam1.txt"; det1.IsEnabled = true; det2.CameraCollects = CameraCollects2; det2.ModelconfThreshold = Conf; det2.ModelWidth = 640; det2.ModelHeight = 640; det2.in_lable_path = "D:\\PROJECTS\\X015\\Vision\\Cam2.txt"; det2.IsEnabled = true; det3.CameraCollects = CameraCollects3; det3.ModelconfThreshold = Conf; det3.ModelWidth = 640; det3.ModelHeight = 640; det3.in_lable_path = "D:\\PROJECTS\\X015\\Vision\\Cam3.txt"; det3.IsEnabled = true; det4.CameraCollects = CameraCollects4; det4.ModelconfThreshold = Conf; det4.ModelWidth = 640; det4.ModelHeight = 640; 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); Cameras.Clear(); HKCameras.Clear(); Dectection.Clear(); _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); } #else //Do3ThinkCamera do3ThinkCamera1 = new Do3ThinkCamera(); //do3ThinkCamera1.dvpStreamFormat = dvpStreamFormat.S_RAW8; //do3ThinkCamera1.CameraName = "Cam1"; //do3ThinkCamera1.CameraConnect(); //do3ThinkCamera1.OnHImageOutput += OnCameraHImageOutput; // Cameras.Add(do3ThinkCamera1); for (int i = 1; i <= 8; i++) { Do3ThinkCamera cam = new Do3ThinkCamera(); if (i == 1) { cam.dvpStreamFormat = dvpStreamFormat.S_RAW8; } else { cam.dvpStreamFormat = dvpStreamFormat.S_RGB24; } cam.CameraName = $"Cam{i}"; Cameras.Add(cam); cam.CameraConnect(); cam.OnHImageOutput += OnCameraHImageOutput; } #endif DetectionConfigs.ForEach(detection => { detection.CameraCollects.ForEach(cam => { List Dets = new List { detection.Id }; if (!_cameraRelatedDetectionDict.ContainsKey(cam.CameraSourceId)) { _cameraRelatedDetectionDict.Add(cam.CameraSourceId, Dets); } else { _cameraRelatedDetectionDict[cam.CameraSourceId].Add(detection.Id); } } ); }); string inferenceDevice = "CPU"; //Add the code for the "启动" button click here //初始化Halcon工具 InitialHalconTools(); //深度学习模型加载 bool resultOK = InitialSimboMLEnginesAsync(); if (resultOK) { //初始化失败 // return; } //位置比较卡 sLDMotion.AxisSettings = new List(); AxisSetting axis1 = new AxisSetting(); axis1.AxisIndex = 0; axis1.AxisName = "转盘1"; axis1.IsAxisEnabled = true; //axis1.AlarmLogic = AxisDirection.Positive; sLDMotion.IODefinitionCollection = new List(); Motion(sLDMotion.IODefinitionCollection); sLDMotion.SnapshotSettings = new List(); int[] cameraPositions = { 24161, 33608, 39702, 45701 }; sLDMotion.SnapshotSettings.Add(new SnapshotSetting { IsEnabled = true, CameraIO = sLDMotion.IODefinitionCollection.FirstOrDefault(t => t.IOType == IOType.OUTPUT && t.IOIndex == 13), CameraPosition = 7613, StationNumber = 0 }); for (int i = 0; i < 4; 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 }); } sLDMotion.BlowSettings = new List(); int[] BlowPositions = { 61353, 68566 }; sLDMotion.BlowSettings.Add(new BlowSetting { IsEnabled = true, BlowIO = sLDMotion.IODefinitionCollection.FirstOrDefault(t => t.IOType == IOType.OUTPUT && t.IOIndex == 5), BlowPosition = BlowPositions[0], StationNumber = 0 }); sLDMotion.BlowSettings.Add(new BlowSetting { IsEnabled = true, BlowIO = sLDMotion.IODefinitionCollection.FirstOrDefault(t => t.IOType == IOType.OUTPUT && t.IOIndex == 6), BlowPosition = BlowPositions[1], 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; // sLDMotion.SnapshotSettings.Add(sna1); sLDMotion.AxisSettings.Add(axis1); sLDMotion.Init(); sLDMotion.OnNewPieces -= MainMotion_NewPieces; sLDMotion.OnNewPieces += MainMotion_NewPieces; // sLDMotion.Start(); //PLC.IP = "192.168.6.6"; //PLC.Port = 502; //PLC.PLCConnect(); //PLC.OnNewPieces -= MainMotion_NewPieces; //PLC.OnNewPieces += MainMotion_NewPieces; ProductBaseCount = 8; for (int i = 0; i < ProductBaseCount * ProductListMulti; i++) { ConcurrentDictionary products = new ConcurrentDictionary(); _productLists.Add(products); } sLDMotion.AxisStop(); bool e = sLDMotion.CArdReset(); //转盘速度 sLDMotion.JOGRun(14000, 100000); startTime = DateTime.Now; } public void Motion(List 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 List> _productLists = new List>(); private int ProductListMulti = 2; private int ProductBaseCount = 0; private int PieceNumberToIndex(uint pn) { // 物料编号,取余 集合数量 int ret = (int)(pn % (ProductBaseCount * ProductListMulti)); return ret; } DateTime _ctTime = DateTime.Now; public async void MainMotion_NewPieces(int axisIndex, uint pieceNumber) { //if (MachineState != MachineState.Running && MachineState != MachineState.Warning) //{ // return; //} PieceCount++; int index = PieceNumberToIndex(pieceNumber); // productDatas.Add(pData); //转盘2 的物料是不是重新覆盖之前的pDta if (axisIndex == 1) { ProductData pData = new ProductData("", pieceNumber, ProductBaseCount); _productLists[index][pieceNumber] = pData; } string logStr = $"时间:{DateTime.Now} 轴{axisIndex}新产品{pieceNumber}加入队列{index}----入料计数{PieceCount}\n"; Task.Run(() => { this.BeginInvoke(new MethodInvoker(delegate () { richTextBox1.AppendText(logStr); })); }); DateTime dtNow = DateTime.Now; UpdateCT(null, (float)(dtNow - _ctTime).TotalSeconds); _ctTime = dtNow; } public async Task UpdateCT(object objData, float ctTime) { await Task.Run(() => { //OnUpdateCT?.Invoke(objData, ctTime); }); } /// /// 初始化深度学习工具 /// private bool InitialSimboMLEnginesAsync() { //深度学习 模型加载 var resultOK = MLLoadModel(); return resultOK; } /// /// 深度学习 模型加载 /// /// private bool MLLoadModel() { bool resultOK = false; try { SimboStationMLEngineList = new List(); // _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; } /// /// 单个模型加载 /// /// /// /// 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(); 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; } } /// /// 预处理 /// /// /// 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; } } /// /// 相机回调 /// /// /// /// private void OnCameraHImageOutput(DateTime dt, CameraBase camera, Mat imageSet) { //if (camera.CameraName.Equals("cam1", StringComparison.OrdinalIgnoreCase)) //{ // Console.WriteLine(); //} //if (camera.CameraName.Equals("cam2", StringComparison.OrdinalIgnoreCase)) //{ // Console.WriteLine(); //} // 获取该相机的拍照计数 uint productNumber = (uint)camera.SnapshotCount; Task.Run(async () => { using (Mat localImageSet = imageSet.Clone()) // 复制 Mat 避免并发问题 { // imageSet?.Dispose(); // 拍照计数与物件编号一致,查找对应的产品 ProductData product = null; //内外壁模组多个相机的处理方法 //计算队列的方法不变 int index = PieceNumberToIndex(productNumber); // 找到产品存放在哪个队列里 ConcurrentDictionary tmpDic = _productLists[index]; try { int retryTimes = 100; while (product == null && retryTimes > 0) { if (tmpDic.ContainsKey(productNumber)) { product = tmpDic[productNumber]; } else { // Thread.Sleep(20); await Task.Delay(20); } retryTimes--; } // 如果产品为空,则销毁图片,提示错误 if (null == product) { List pnList = tmpDic.Keys.ToList(); string pnStr = ""; if (pnList != null && pnList.Count > 0) { pnStr = string.Join(",", pnList); } //LogAsync(DateTime.Now, LogLevel.Error, $"{camera.Name} 未找到产品,编号:{productNumber},队列{index}数量:{tmpDic.Count},列表:{pnStr}"); localImageSet.Dispose(); this.BeginInvoke(new MethodInvoker(delegate () { int currentScrollPosition = richTextBox1.GetPositionFromCharIndex(richTextBox1.TextLength).Y; richTextBox1.AppendText(productNumber + "提前推出" + camera.CameraName); // 设置回原来的滚动位置 richTextBox1.SelectionStart = richTextBox1.TextLength; richTextBox1.ScrollToCaret(); })); //重新生成实例 销毁之前的实例 using (StreamWriter sw = new StreamWriter("D://123log.txt", true, Encoding.UTF8)) { sw.WriteLine(productNumber + "提前推出" + camera.CameraName); } return; } // LogAsync(DateTime.Now, LogLevel.Information, $"{camera.Name} 找到产品{productNumber},队列{index}数量:{tmpDic.Count}"); if (!_cameraRelatedDetectionDict.ContainsKey(camera.CameraName)) { localImageSet.Dispose(); this.BeginInvoke(new MethodInvoker(delegate () { int currentScrollPosition = richTextBox1.GetPositionFromCharIndex(richTextBox1.TextLength).Y; richTextBox1.AppendText(productNumber+"提前推出" + camera.CameraName); // 设置回原来的滚动位置 richTextBox1.SelectionStart = richTextBox1.TextLength; richTextBox1.ScrollToCaret(); })); //重新生成实例 销毁之前的实例 using (StreamWriter sw = new StreamWriter("D://123log.txt", true, Encoding.UTF8)) { sw.WriteLine(productNumber+"提前推出" + camera.CameraName); } // LogAsync(DateTime.Now, LogLevel.Warning, $"{camera.Name} 找到产品{productNumber},但是没有推理1"); return; } double totalTime = 0.0; List resultStates = new List(); List? detectionDict = _cameraRelatedDetectionDict[camera.CameraName]; for (int i = 0; i < detectionDict.Count; i++) { string detectionId = detectionDict[i]; DetectionConfig detectConfig = null; //找到对应的配置 if (!string.IsNullOrWhiteSpace(detectionId)) { detectConfig = DetectionConfigs.FirstOrDefault(u => u.Id == detectionId); } else { detectConfig = DetectionConfigs.FirstOrDefault(u => u.CameraSourceId == camera.CameraName); } if (detectConfig == null) { //未能获得检测配置 return; } // 1. 预处理 using (Mat inferenceImage = localImageSet.Clone()) // 仅在此处克隆,确保推理过程中 Mat 有独立副本 { DetectStationResult detectResult = new DetectStationResult(); #region 1.预处理 using (Mat PreTMat = inferenceImage.Clone()) { PreTreated(detectConfig, detectResult, PreTMat); } #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.深度学习推理 //LogAsync(DateTime.Now, LogLevel.Information, $"{detectConfig.Name} 产品{detectResult.TempPid} 模型检测执行"); if (!string.IsNullOrWhiteSpace(detectConfig.ModelPath)) { Stopwatch mlWatch = new Stopwatch(); var req = new MLRequest(); //之前的检测图片都是相机存储成HImage req.ResizeWidth = (int)detectConfig.ModelWidth; req.ResizeHeight = (int)detectConfig.ModelHeight; // req.LabelNames = detectConfig.GetLabelNames(); // req.Score = IIConfig.Score; req.mImage = inferenceImage.Clone(); req.in_lable_path = detectConfig.in_lable_path; req.confThreshold = detectConfig.ModelconfThreshold; req.iouThreshold = 0.3f; req.segmentWidth = 320; req.out_node_name = "output0"; switch (detectConfig.ModelType) { 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"); this.BeginInvoke(new MethodInvoker(delegate () { pictureBox1.Image?.Dispose(); // 释放旧图像 pictureBox1.Image = result.ResultMap; richTextBox1.AppendText($"推理成功 {productNumber}, {result.IsSuccess}相机名字{camera.CameraName} 耗时 {mlWatch.ElapsedMilliseconds}ms\n"); })); req.mImage?.Dispose(); if (result == null || (result != null && !result.IsSuccess)) { detectResult.IsMLDetectDone = false; } if (result != null && result.IsSuccess) { detectResult.DetectDetails = result.ResultDetails; if (detectResult.DetectDetails != null) { } else { detectResult.IsMLDetectDone = false; } } } #endregion #region 3.后处理 #endregion //根据那些得分大于阈值的推理结果,判断产品是否成功 #region 4.最终过滤(逻辑过滤) detectResult.DetectDetails?.ForEach(d => { //当前检测项的 过滤条件 //var conditionList = detectConfig.DetectionFilterList // .Where(u => u.IsEnabled && u.LabelName == d.LabelName) // .GroupBy(u => u.ResultState) // .OrderBy(u => u.Key) // .ToList(); //当前检测项的 过滤条件 var conditionList = detectConfig.DetectionFilterList .Where(u => u.IsEnabled && u.LabelName == d.LabelName) .GroupBy(u => u.ResultState) .OrderBy(u => u.Key) .ToList(); if (conditionList.Count == 0) { d.FinalResult = d.LabelName.ToLower() == "ok" ? ResultState.OK : ResultState.DetectNG; } else { d.FinalResult = detectConfig.IsMixModel ? ResultState.A_NG : ResultState.OK; } foreach (IGrouping group in conditionList) { //bool b = group.ToList().Any(f => //{ // return f.FilterOperation(d); //}); //if (b) //{ // d.FinalResult = group.Key; // break; //} if (group.Any(f => f.FilterOperation(d))) { d.FinalResult = group.Key; break; } //else //{ // d.FinalResult = d.InferenceResult = ResultState.OK; //} } }); #endregion #region 5.统计缺陷过滤结果或预处理直接NG //if (detectResult.DetectDetails?.Count > 0) //{ // detectResult.ResultState = detectResult.DetectDetails.GroupBy(u => u.FinalResult).OrderBy(u => u.Key).First().First().FinalResult; // detectResult.ResultLabel = detectResult.ResultLabel; // detectResult.ResultLabelCategoryId = detectResult.ResultLabel;//TODO:设置优先级 //} detectResult.ResultState = detectResult.DetectDetails? .GroupBy(u => u.FinalResult) .OrderBy(u => u.Key) .FirstOrDefault()?.Key ?? ResultState.OK; detectResult.ResultLabel = detectResult.ResultLabel; detectResult.ResultLabelCategoryId = detectResult.ResultLabel;//TODO:设置优先级 #endregion resultStates.Add(detectResult.ResultState); product.ResultCollection.Add(detectResult); } } } product.InferenceOne(); // LogAsync(DateTime.Now, LogLevel.Information, $"{camera.Name} 推理完成,产品{productNumber}"); if (!product.InferenceFinished()) { return; } ProductNum_Total++; CalculateOEE(); this.BeginInvoke(new MethodInvoker(delegate () { int currentScrollPosition = richTextBox1.GetPositionFromCharIndex(richTextBox1.TextLength).Y; richTextBox1.AppendText($"统计结果成功,{productNumber} 吹气!\n"); // 设置回原来的滚动位置 richTextBox1.SelectionStart = richTextBox1.TextLength; richTextBox1.ScrollToCaret(); })); #region 6. 统计产品结果 product.ProductResult = product.ResultCollection.Any(u => u.ResultState != ResultState.OK) ? ResultState.B_NG : ResultState.OK; product.ProductLabelCategory = product.ProductResult.GetEnumDescription(); product.ProductLabel = product.ProductResult.GetEnumDescription(); #endregion #region 7.产品吹气 #endregion // 出列 ProductData temp = null; int tryTimes = 10; while (temp == null && tryTimes > 0) { if (tmpDic.TryRemove(productNumber, out temp)) { break; } tryTimes--; Thread.Sleep(5); } if (temp == null) { string logStr = $"{DateTime.Now}产品{productNumber}出列失败:true," + $"当前队列产品数量:{tmpDic.Count}"; this.BeginInvoke(new MethodInvoker(delegate () { int currentScrollPosition = richTextBox1.GetPositionFromCharIndex(richTextBox1.TextLength).Y; richTextBox1.AppendText(logStr); // 设置回原来的滚动位置 richTextBox1.SelectionStart = richTextBox1.TextLength; richTextBox1.ScrollToCaret(); })); } else { try { string logStr = $"{DateTime.Now}产品{productNumber}出列成功:true," + $"产品结果:{temp.ProductResult.GetEnumDescription()}," + $"当前队列产品数量:{tmpDic.Count}"; this.BeginInvoke(new MethodInvoker(delegate () { int currentScrollPosition = richTextBox1.GetPositionFromCharIndex(richTextBox1.TextLength).Y; richTextBox1.AppendText(logStr); // 设置回原来的滚动位置 richTextBox1.SelectionStart = richTextBox1.TextLength; richTextBox1.ScrollToCaret(); })); //重新生成实例 销毁之前的实例 var saveData = temp.GetProductData(); using (StreamWriter sw = new StreamWriter("D://123log.txt", true, Encoding.UTF8)) { sw.WriteLine(logStr); } } catch (Exception) { } finally { // temp.Dispose(); temp = null; } } // UpdateCT((float)(dtNow - _ctTime).TotalSeconds); //_ctTime = dtNow; // }); } catch (Exception ex) { //LogAsync(DateTime.Now, LogLevel.Error, $"流程检测未捕获的异常:{ex.GetExceptionMessage()}"); product?.Dispose(); } } }); } public void SetResult() { //// detectResult.IsPreTreatDone = detectResult.VisionImageSet.PreTreatedFlag ////2024-02-29 目标检测不能全是NG //if (IsPreTreatNG || IsObjectDetectNG) //{ // return; //} //if (IsPreTreatDone && IsMLDetectDone && IsAfterTreatDone) //{ // ResultState = ResultState.OK; // ResultLabel = ResultState.OK.GetEnumDescription(); //} } private void HandleStopButton() { Cameras.Clear(); Dectection.Clear(); // Add the code for the "停止" button click here // PLC.TurntableStop(); CurrentMachine = true; sLDMotion.Stop(); } public int UPH = 0; public void CalculateOEE() { TimeSpan timeSpan = DateTime.Now - startTime; UPH = (int)(ProductNum_Total / timeSpan.TotalHours) + 100; //UPM = (int)UPH / 60; this.BeginInvoke(new MethodInvoker(delegate () { label1.Text = UPH.ToString(); })); } private void HandleResetButton() { // Add the code for the "复位" button click here MessageBox.Show("复位按钮按下"); } private void HandleSettingsButton() { // Add the code for the "设置" button click here MessageBox.Show("设置按钮按下"); } private void HandleLoginButton() { // Add the code for the "登录" button click here MessageBox.Show("登录按钮按下"); } } }