DHDHSoftware/DHSoftware/MainWindow.cs
2025-03-12 17:18:39 +08:00

1501 lines
59 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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<string, List<string>> _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<Camera> Cameras = new List<Camera>
{
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<HikVisionCamera> HKCameras { get; } = new List<HikVisionCamera>();
public List<Do3ThinkCamera> Cameras { get; } = new List<Do3ThinkCamera>();
public Dictionary<string, SimboObjectDetection> Dectection { get; } = new Dictionary<string, SimboObjectDetection>();
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<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 DateTime startTime;
private void HandleStartButton()
{
CurrentMachine = true;
//[Category("深度学习检测配置")]
//[DisplayName("检测标签定义集合")]
//[Description("定义检测标签的集合例如Seg/Detection模式断裂、油污、划伤...Class模式ok、ng、上面、下面、套环、正常...")]
//[TypeConverter(typeof(CollectionCountConvert))]
//[Editor(typeof(ComplexCollectionEditor<RecongnitionLabel>), 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<RelatedCamera> CameraCollects = new List<RelatedCamera>();
CameraCollects.Add(new RelatedCamera("Cam1"));
List<RelatedCamera> CameraCollects2 = new List<RelatedCamera>();
CameraCollects2.Add(new RelatedCamera("Cam2"));
List<RelatedCamera> CameraCollects3 = new List<RelatedCamera>();
CameraCollects3.Add(new RelatedCamera("Cam3"));
List<RelatedCamera> CameraCollects4 = new List<RelatedCamera>();
CameraCollects4.Add(new RelatedCamera("Cam4"));
List<RelatedCamera> CameraCollects5 = new List<RelatedCamera>();
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;
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<string> Dets = new List<string>
{
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>();
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);
sLDMotion.SnapshotSettings = new List<SnapshotSetting>();
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<BlowSetting>();
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<uint, ProductData> products = new ConcurrentDictionary<uint, ProductData>();
_productLists.Add(products);
}
sLDMotion.AxisStop();
bool e = sLDMotion.CArdReset();
//转盘速度
sLDMotion.JOGRun(14000, 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 List<ConcurrentDictionary<uint, ProductData>> _productLists = new List<ConcurrentDictionary<uint, ProductData>>();
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);
});
}
/// <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)
{
//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<uint, ProductData> 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<uint> 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<ResultState> resultStates = new List<ResultState>();
List<string>? 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<ResultState, DetectionFilter> 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("登录按钮按下");
}
}
}