using AntdUI; using AntdUI.Svg; using DH.Devices.Camera; using DH.Devices.PLC; using DH.Devices.Vision; using DHSoftware.Languages; using DHSoftware.Models; using DHSoftware.Utils; using DVPCameraType; using Microsoft.Win32; using OpenCvSharp; using System; using System.CodeDom; using System.Collections.Concurrent; using System.Collections.Generic; using System.Drawing; using System.Linq; using System.Runtime.InteropServices; using System.Threading.Tasks; using System.Windows.Forms; 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 Cameras { get; } = new List(); public Dictionary Dectection { get; } = new Dictionary(); public XinJEPLCTcpNet PLC { get; } = new XinJEPLCTcpNet(); private void MainWindow_Load(object sender, EventArgs e) { } private void MainWindow_FormClosed(object sender, FormClosedEventArgs e) { foreach (var camera in Cameras) { 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(); public DateTime sraerttime; private void HandleStartButton() { CurrentMachine = true; List detectionList = new List(); detectionList.Add(new VisionEngine("相机1", MLModelType.ObjectDetection, @"D:\DHSoftware\DHSoftware\Models\yolov3.cfg", false, "Cam1")); detectionList.Add(new VisionEngine("相机2", MLModelType.ObjectDetection, @"D:\DHSoftware\DHSoftware\Models\yolov3.cfg", false, "Cam2")); detectionList.Add(new VisionEngine("相机3", MLModelType.ObjectDetection, @"D:\DHSoftware\DHSoftware\Models\yolov3.cfg", false, "Cam3")); detectionList.Add(new VisionEngine("相机4", MLModelType.ObjectDetection, @"D:\DHSoftware\DHSoftware\Models\yolov3.cfg", false, "Cam4")); _cameraRelatedDetectionDict = new(); detectionList.ForEach(detection => { // detection.CameraCollects.ForEach(cam => { List Dets = new List { detection.Id }; if (!_cameraRelatedDetectionDict.ContainsKey(detection.CameraSourceId)) { _cameraRelatedDetectionDict.Add(detection.CameraSourceId, Dets); } else { _cameraRelatedDetectionDict[detection.CameraSourceId].Add(detection.Id); } } //); }); //Add the code for the "启动" button click here Do3ThinkCamera do3ThinkCamera1 = new Do3ThinkCamera(); do3ThinkCamera1.dvpStreamFormat = dvpStreamFormat.S_MONO8; do3ThinkCamera1.CameraName = "Cam1"; Do3ThinkCamera do3ThinkCamera2 = new Do3ThinkCamera(); do3ThinkCamera2.dvpStreamFormat = dvpStreamFormat.S_RGB24; do3ThinkCamera2.CameraName = "Cam2"; Cameras.Add(do3ThinkCamera1); Cameras.Add(do3ThinkCamera2); do3ThinkCamera1.CameraConnect(); do3ThinkCamera2.CameraConnect(); do3ThinkCamera1.OnHImageOutput += OnCameraHImageOutput; do3ThinkCamera2.OnHImageOutput += OnCameraHImageOutput; var simbo1 = new SimboObjectDetection { }; MLInit mLInit; string inferenceDevice = "CPU"; mLInit = new MLInit($"D:\\PROJECTS\\MaodingTest1\\Vision\\cam1.onnx", "images", inferenceDevice, 640, 640); simbo1.Load(mLInit); Dectection.Add(do3ThinkCamera1.CameraName, simbo1); var simbo2 = new SimboObjectDetection { }; MLInit mLInit2; string inferenceDevice2 = "CPU"; mLInit2 = new MLInit($"D:\\PROJECTS\\MaodingTest1\\Vision\\cam2.onnx", "images", inferenceDevice2, 640, 640); simbo2.Load(mLInit2); Dectection.Add(do3ThinkCamera2.CameraName, simbo2); PLC.IP = "192.168.6.6"; PLC.Port = 502; PLC.PLCConnect(); PLC.OnNewPieces -= MainMotion_NewPieces; PLC.OnNewPieces += MainMotion_NewPieces; ProductBaseCount = 2; for (int i = 0; i < ProductBaseCount * ProductListMulti; i++) { ConcurrentDictionary products = new ConcurrentDictionary(); _productLists.Add(products); } sraerttime=DateTime.Now; } private uint PieceCount = 0; private List> _productLists = new List>(); private int ProductListMulti = 2; private int ProductBaseCount = 0; 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)); return ret; } DateTime _ctTime = DateTime.Now; public async void MainMotion_NewPieces(int axisIndex, uint pieceNumber) { //if (MachineState != MachineState.Running && MachineState != MachineState.Warning) //{ // return; //} PieceCount++; Task.Run(() => { this.BeginInvoke(new MethodInvoker(delegate () { richTextBox1.AppendText("入料成功" + PieceCount); })); }); int index = PieceNumberToIndex(pieceNumber); // productDatas.Add(pData); //转盘2 的物料是不是重新覆盖之前的pDta if (axisIndex == 1) { ProductData pData = new ProductData("", pieceNumber, ProductBaseCount); _productLists[index][pieceNumber] = pData; } 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 void OnCameraHImageOutput(DateTime dt, CameraBase camera, Mat imageSet) { // 获取该相机的拍照计数 uint productNumber = (uint)camera.SnapshotCount; Task.Run(async () => { // 拍照计数与物件编号一致,查找对应的产品 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); } 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}"); imageSet.Dispose(); return; } // LogAsync(DateTime.Now, LogLevel.Information, $"{camera.Name} 找到产品{productNumber},队列{index}数量:{tmpDic.Count}"); if (!_cameraRelatedDetectionDict.ContainsKey(camera.CameraName)) { if (imageSet != null) { imageSet?.Dispose(); imageSet = null; } imageSet.Dispose(); // LogAsync(DateTime.Now, LogLevel.Warning, $"{camera.Name} 找到产品{productNumber},但是没有推理1"); return; } double totalTime = 0.0; List resultStates = new List(); List? detectionDict = _cameraRelatedDetectionDict[camera.CameraName]; if (detectionDict.Count == 0) { //LogAsync(DateTime.Now, LogLevel.Warning, $"{camera.Name} 找到产品{productNumber},但是没有推理3"); } for (int i = 0; i < detectionDict.Count; i++) { string d = detectionDict[i]; try { // LogAsync(DateTime.Now, LogLevel.Information, $"{camera.Name} 推理进度1.3,产品{productNumber}"); var req = new MLRequest(); req.mImage = imageSet.Clone(); req.ResizeWidth = 640; req.ResizeHeight = 640; req.confThreshold = 0.5f; req.iouThreshold = 0.3f; req.out_node_name = "output0"; req.in_lable_path = "D:\\PROJECTS\\MaodingTest1\\Vision\\cam1.txt"; //req.LabelNames = dc.GetLabelNames(); req.Score = 0.5f; //HOperatorSet.WriteImage(req.HImage, "png", 0, @"D:\\666.png"); var result = Dectection[camera.CameraName].RunInference(req); this.BeginInvoke(new MethodInvoker(delegate () { pictureBox1.Image = result.ResultMap; richTextBox1.AppendText("推理成功" + productNumber+ result.IsSuccess+ "\n"); })); //DetectStationResult temp; ////LogAsync(DateTime.Now, LogLevel.Information, $"{camera.Name} 推理进度1.4,产品{productNumber}"); //// 检测结果 //if (temp != null) //{ // // LogAsync(DateTime.Now, LogLevel.Information, $"{camera.Name} 推理进度1.5,产品{productNumber}"); // //var totalElapsed = (temp.EndTime - temp.VisionImageSet.ImageTime).TotalMilliseconds; // //totalTime += totalElapsed; // resultStates.Add(temp.ResultState); // product.ResultCollection.Add(temp); // // LogAsync(DateTime.Now, LogLevel.Information, $"{camera.Name} 推理进度1.6,产品{productNumber}"); //} //else //{ // //LogAsync(DateTime.Now, LogLevel.Information, $"{camera.Name} 检测失败,物料编号:{productNumber},检测项:{d}"); //} imageSet.Dispose(); } catch (Exception ex) { // LogAsync(DateTime.Now, LogLevel.Information, $"{camera.Name} 推理异常,物料编号:{productNumber},检测项:{d}, {ex.GetExceptionMessage}"); } } //detectionDict.ForEach(d => //{ //}); // LogAsync(DateTime.Now, LogLevel.Information, $"{camera.Name} 推理进度2,产品{productNumber}"); imageSet.Dispose(); product.InferenceOne(() => { ; }, () => { ; }); // LogAsync(DateTime.Now, LogLevel.Information, $"{camera.Name} 推理完成,产品{productNumber}"); if (!product.InferenceFinished()) { //if (!(camera.Name == "Cam8")) //{ // return; //} 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(); })); //LogAsync(DateTime.Now, LogLevel.Information, $"推理完成,产品{product.PieceNumber}获取结果"); // 统计产品结果 //Task resultTask = product.SetProductResult(_totalDetectionNum, X017Config.IsTBDPriority, labelCategoryLists); //await resultTask.ContinueWith(t => //{ // try // { // UpdateTriggerCount(DateTime.Now, "获取结果"); // UpdateResult(DateTime.Now, camera, product.ProductResult.GetEnumDescription()); // UpdateResultNew(DateTime.Now, camera, "合计"); // LogAsync(DateTime.Now, LogLevel.Information, $"产品{product.PieceNumber}获取结果:{product.ProductResult} {(product.IsA2B ? "产品IsA2B" : "")}"); // } // catch (Exception ex) // { // LogAsync(DateTime.Now, LogLevel.Information, $"产品{product.PieceNumber}获取结果异常:{product.ProductResult} {(product.IsA2B ? "产品IsA2B" : "")}," + // $"异常信息:{ex.GetExceptionMessage}"); // } // // 吹气 // DateTime dtNow = DateTime.Now; // product.BlowOutTime = dtNow; // var setting = X017Config.ProductBlowSettings.FirstOrDefault(s => product.ProductResult.Equals(s.ProductResult)); // if (setting != null) // { // uint NGNumC = 0; // uint OKNumC = 0; // CMCDLL_NET.MCF_Sorting_Get_Lose_Blow_NG_Count_Net(ref NGNumC, 0); // CMCDLL_NET.MCF_Sorting_Get_Lose_Blow_OK_Count_Net(ref OKNumC, 0); // _mainMotion.Blow(product.PieceNumber, setting.BindBlow); // LogAsync(DateTime.Now, LogLevel.Action, $"产品{product.PieceNumber}吹气{NGNumC}+ {OKNumC}"); // //if (product.ProductResult == ResultState.OK) // //{ // // //OKProcessNum++; // // OKNum++; // //} // } // //判断超时出队 // foreach (var kvp in tmpDic) // { // try // { // ProductData dataN = kvp.Value; // TimeSpan timeDifference = DateTime.Now - dataN.CreateTime; // if (timeDifference.TotalMinutes >= 1) // { // //出队 // bool isremoved = tmpDic.TryRemove(kvp.Key, out _); // if (isremoved) // { // LogAsync(DateTime.Now, LogLevel.Error, $"====产品{kvp.Key}超时出列成功" + // $"产品结果:{dataN.ProductResult.GetEnumDescription()} {dataN.ProductResult}," + // $"当前队列产品数量:{tmpDic.Count}===="); // try // { // //重新生成实例 销毁之前的实例 // var saveData = dataN.GetProductData(); // var productDefects = dataN.GetDetectDetailData(); // SaveProductDataAsync(saveData, productDefects); // dataN = null; // } // catch (Exception) { } // dataN?.Dispose(); // } // else // { // LogAsync(DateTime.Now, LogLevel.Error, $"=====产品{kvp.Key}超时出列失败" + // $"当前队列产品数量:{tmpDic.Count}====="); // } // } // } // catch (Exception ex) // { // LogAsync(DateTime.Now, LogLevel.Error, $"=====产品{kvp.Key}超时出列失败" + // $"当前队列产品数量:{tmpDic.Count}====={ex.GetExceptionMessage}"); // } // } // 出列 ProductData temp = null; int tryTimes = 5; while (temp == null && tryTimes > 0) { var isSuccess = tmpDic.Remove(productNumber, out temp); if (isSuccess) { // LogAsync(DateTime.Now, LogLevel.Assist, $"产品{productNumber}出列成功:{isSuccess}," + //$"产品结果:{temp.ProductResult.GetEnumDescription()}," + //$"当前队列产品数量:{tmpDic.Count}"); } tryTimes--; Thread.Sleep(1); } if (temp == null) { //LogAsync(DateTime.Now, LogLevel.Assist, $"产品{productNumber}出列失败," + // $"当前队列产品数量:{tmpDic.Count}"); } else { try { //重新生成实例 销毁之前的实例 var saveData = temp.GetProductData(); } 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(); } }); } private void HandleStopButton() { Cameras.Clear(); Dectection.Clear(); // Add the code for the "停止" button click here PLC.TurntableStop(); CurrentMachine = true; } public int UPH=0; public void CalculateOEE() { TimeSpan timeSpan = DateTime.Now - sraerttime; 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("登录按钮按下"); } } }