using Cognex.VisionPro; using Cognex.VisionPro.QuickBuild; using LampInspectionMachine.Cameralibs; using LampInspectionMachine.Model; using MvCamCtrl.NET; using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Linq; using System.Text; using System.Threading.Tasks; using Prism.Mvvm; using LampInspectionMachine.Log4xml; using Cognex.VisionPro.ImageFile; using System.Drawing; using System.Windows.Forms; using System.Web; using System.ComponentModel; using System.Windows.Media.Media3D; using LampInspectionMachine.ViewModels; using System.Collections.Concurrent; using System.Threading; using System.Windows.Controls; using LampInspectionMachine.Views; using System.Windows.Media.Imaging; using System.Windows.Media; using System.Windows; using System.Runtime.InteropServices; using SqlSugar.DistributedSystem.Snowflake; using System.Windows.Threading; using System.Windows.Ink; using System.Data.SqlClient; using System.Xml.Linq; using System.Drawing.Imaging; using System.IO.Packaging; using Cognex.VisionPro.ToolBlock; using System.Windows.Markup; using System.Diagnostics; using LampInspectionMachine.Cameralibs.HKCamera; using Newtonsoft.Json.Linq; using OpenCvSharp.Dnn; using LampInspectionMachine.Interfaces; namespace LampInspectionMachine.Core { public class Management : BindableBase { private bool isConnected = false; private CogJobManager myJobManager; private List myJobs = new List(); private List myIndependentJobs = new List(); private CameraView cameraView; private ICogImage image = new CogImage8Grey(); private WriteableBitmap writeable; public WriteableBitmap Writeable { get => writeable; set { SetProperty(ref writeable, value); } } public ICogImage Image { get => image; set { SetProperty(ref image, value); } } // 使用泛型委托 public event EventHandler PropertyChanged; // 或者自定义委托 public delegate void ChangeEventHandler(ICogImage e); public event ChangeEventHandler OnChange; public CameraService CameraService { get; set; } public CogJobManager MyJobManager { get => myJobManager; set => myJobManager = value; } public List MyJobs { get => myJobs; set => myJobs = value; } public List MyIndependentJobs { get => myIndependentJobs; set => myIndependentJobs = value; } public CogJobManagerEdit MyJobManagerEdit { get => myJobManagerEdit; set => myJobManagerEdit = value; } /// /// 相机列表 /// public ObservableCollection CameraList { get => _CameraList; set { SetProperty(ref _CameraList, value); } } /// /// 当前相机配置 /// public CameraInfo CurrCamConfig { get => _CurrCamConfig; set { SetProperty(ref _CurrCamConfig, value); } } /// /// 相机配置列表 /// public ObservableCollection CamConfigs { get => _CamConfigs; set { SetProperty(ref _CamConfigs, value); } } public bool IsTriggerModel { get => _isTriggerModel; set { SetProperty(ref _isTriggerModel, value); } } public ICamera MyCamera { get => myCamera; set { SetProperty(ref myCamera, value); } } /// /// 相机对应模板工具 /// public List CamTemplateS { get => _CamTemplateS; set => _CamTemplateS = value; } public event Action ToolBlockSwitched; /// /// 当前选中相机的SN /// public string CurrCameraSn { get => _CurrCameraSn; set { SetProperty(ref _CurrCameraSn, value); } } private ObservableCollection _CamConfigs = new ObservableCollection(); private List _CamTemplateS = new List(); private CogToolBlock cogToolBlock1; private CameraInfo _CurrCamConfig = null; private ICamera myCamera; private bool _isTriggerModel = false; /// /// 当前需要显示的工程文件 /// private CogJobManagerEdit myJobManagerEdit; private ObservableCollection _CameraList = new ObservableCollection(); private string _CurrCameraSn = ""; public Stopwatch stopwatch = new Stopwatch(); public Management() { } /// /// 获取相机列表 /// public void LoadCameraDevice() { CameraService = new CameraService(); CameraList = FindLoadCamera(); if (CamConfigs.Count == 0) { CamConfigs.Add(new CameraInfo() { VppFileName = "Cam1.vpp" }); CamConfigs.Add(new CameraInfo() { VppFileName = "Cam2.vpp" }); CamConfigs.Add(new CameraInfo() { VppFileName = "Cam3.vpp" }); CamConfigs.Add(new CameraInfo() { VppFileName = "Cam4.vpp" }); CamConfigs.Add(new CameraInfo() { VppFileName = "Cam5.vpp" }); CamConfigs.Add(new CameraInfo() { VppFileName = "Cam6.vpp" }); } } public void SaveCameraDevice() { } /// /// 初始化模板 /// public void InitTemplates(TipService tipService) { tipService.ShowMsg("相机模板加载2%"); CogToolBlock cogToolBlock = (CogToolBlock)CogSerializer.LoadObjectFromFile(Environment.CurrentDirectory + "\\Vpp\\Cam1.vpp"); CamTemplateS.Add(cogToolBlock); //tipService.ShowMsg("相机模板加载10%"); //cogToolBlock = ( CogToolBlock ) CogSerializer.LoadObjectFromFile(Environment.CurrentDirectory + "\\Vpp\\Cam2.vpp"); //CamTemplateS.Add(cogToolBlock); //tipService.ShowMsg("相机模板加载26%"); //cogToolBlock = ( CogToolBlock ) CogSerializer.LoadObjectFromFile(Environment.CurrentDirectory + "\\Vpp\\Cam3.vpp"); //CamTemplateS.Add(cogToolBlock); //tipService.ShowMsg("相机模板加载39%"); //cogToolBlock = ( CogToolBlock ) CogSerializer.LoadObjectFromFile(Environment.CurrentDirectory + "\\Vpp\\Cam4.vpp"); //CamTemplateS.Add(cogToolBlock); //tipService.ShowMsg("相机模板加载52%"); //cogToolBlock = ( CogToolBlock ) CogSerializer.LoadObjectFromFile(Environment.CurrentDirectory + "\\Vpp\\Cam5.vpp"); //CamTemplateS.Add(cogToolBlock); //tipService.ShowMsg("相机模板加载65%"); //cogToolBlock = ( CogToolBlock ) CogSerializer.LoadObjectFromFile(Environment.CurrentDirectory + "\\Vpp\\Cam6.vpp"); //CamTemplateS.Add(cogToolBlock); //tipService.ShowMsg("相机模板加载78%"); //cogToolBlock = ( CogToolBlock ) CogSerializer.LoadObjectFromFile(Environment.CurrentDirectory + "\\Vpp\\Cam7.vpp"); //CamTemplateS.Add(cogToolBlock); //tipService.ShowMsg("相机模板加载91%"); //cogToolBlock = ( CogToolBlock ) CogSerializer.LoadObjectFromFile(Environment.CurrentDirectory + "\\Vpp\\Cam8.vpp"); //CamTemplateS.Add(cogToolBlock); //tipService.ShowMsg("相机模板加载99%"); tipService.Tcolse(); } /// /// 单张采集 /// public void SoftTrigger() { if (isConnected) { MyCamera.StopGrabbing(); LogHelper.Info($"软触发配置写入"); //MyCamera.SetTriggerModeOff(); //CurrCamConfig.TriggerMode = false; //MyCamera.SetTriggerSoftware(); //if (!MyCamera.CheckImageCallbackEvent(CamCallBack)) // MyCamera.ImageCallbackEvent -= CamCallBack; //if (MyCamera.CheckImageCallbackEvent(CamVisionProCallBack)) // MyCamera.ImageCallbackEvent += CamVisionProCallBack; LogHelper.Info($"软触发取图"); MyCamera.Grab(); } } /// /// 连续采集写入 /// public void SoftTrigger__Continue() { //MyCamera.SetTriggerModeOff(); //CurrCamConfig.TriggerMode = false; //MyCamera.SetTriggerSoftware(); //if (MyCamera.CheckImageCallbackEvent(CamCallBack)) // MyCamera.ImageCallbackEvent += CamCallBack; //if (!MyCamera.CheckImageCallbackEvent(CamVisionProCallBack)) // MyCamera.ImageCallbackEvent -= CamVisionProCallBack; LogHelper.Info($"连续采集启动"); MyCamera.StartGrabbing(); } public void SetHardTrigger_CallBack() { LogHelper.Info($"硬触发模式 启动"); //MyCamera.SetTriggerModeOn(); //CurrCamConfig.TriggerMode = true; //MyCamera.SetTriggerSoftware(0); //if (!MyCamera.CheckImageCallbackEvent(CamCallBack)) // MyCamera.ImageCallbackEvent -= CamCallBack; //if (MyCamera.CheckImageCallbackEvent(CamVisionProCallBack)) // MyCamera.ImageCallbackEvent += CamVisionProCallBack; MyCamera.StartGrabbing(); } /// /// 查找相机 /// public ObservableCollection FindLoadCamera() { var listsn = MvCamera.GetDevices(); if (listsn.Length > 0) { ObservableCollection strings = new ObservableCollection(); for (int i = 0; i < listsn.Length; i++) { //strings.Add(listsn[i].); } return strings; } else { System.Windows.Forms.MessageBox.Show("未查询到设备!", "提示", MessageBoxButtons.OK); return null; } } public void InitCamera(string name) { // 初始化相机 if (isConnected && myCamera != null) { myCamera.CloseDevice(); myCamera = null; } Guid guid = new Guid(); CameraService.CreateCamera(guid, new CameraInfo() { SerialNumber = name }); myCamera = CameraService.GetCamera(guid); bool res = myCamera.OpenDevice(); if (!res) { myCamera.CloseDevice(); myCamera = null; isConnected = false; } else { isConnected = true; } } public void InitCameras() { CameraService = new CameraService(); foreach (var item in CamConfigs) { try { CameraService.CreateCamera(item.Id, item); CameraService.GetCamera(item.Id).CameraConnectChangedEvent += Management_CameraConnectChangedEvent; if (CameraService.GetCamera(item.Id).OpenDevice()) { } else { } } catch (Exception ex) { } } } public void CloseCamera() { myCamera?.StopGrabbing(); myCamera?.CloseDevice(); myCamera = null; isConnected = false; } /// ///图像显示 /// /// private void CamCallBack(ICogImage image, TimeSpan totaltime, string errormessage) { try { Image = image; } finally { } } /// ///图像显示 /// /// private void MainCamCallBack(ICogImage image, TimeSpan totaltime, string errormessage) { try { Image = image; } finally { } } // 将海康相机帧数据转换为CogImage8Grey灰度图像 public static ICogImage ConvertToCogImage(IntPtr pData, ref MyCamera.MV_FRAME_OUT_INFO_EX pFrameInfo) { // 验证像素格式(支持MONO8/RGB8转灰度) if (pFrameInfo.enPixelType != MvCamCtrl.NET.MyCamera.MvGvspPixelType.PixelType_Gvsp_Mono8 && pFrameInfo.enPixelType != MvCamCtrl.NET.MyCamera.MvGvspPixelType.PixelType_Gvsp_RGB8_Packed) { throw new ArgumentException("Unsupported pixel format"); } // 创建CogImage8Grey对象 CogImage8Grey cogImage = new CogImage8Grey(); int width = (int)pFrameInfo.nWidth; int height = (int)pFrameInfo.nHeight; // 分配内存并复制数据 cogImage.Allocate(width, height); // 获取8位灰度图像像素内存区域 ICogImage8PixelMemory pixelMemory = (cogImage).Get8GreyPixelMemory( CogImageDataModeConstants.ReadWrite, 0, 0, cogImage.Width, cogImage.Height); IntPtr destPtr = pixelMemory.Scan0; // 获取像素数据指针 // IntPtr destPtr = cogImage.GetPixelData(CogImageDataModeConstants.ReadWrite); if (pFrameInfo.enPixelType == MvCamCtrl.NET.MyCamera.MvGvspPixelType.PixelType_Gvsp_Mono8) { // 直接拷贝MONO8数据 SafeMemoryCopy(destPtr, pData, width * height); } else // RGB转灰度 { byte[] rgbBuffer = new byte[width * height * 3]; Marshal.Copy(pData, rgbBuffer, 0, rgbBuffer.Length); unsafe { byte* pDest = (byte*)destPtr.ToPointer(); for (int i = 0; i < rgbBuffer.Length; i += 3) { // RGB转灰度公式:0.299*R + 0.587*G + 0.114*B *pDest++ = (byte)(0.299 * rgbBuffer[i] + 0.587 * rgbBuffer[i + 1] + 0.114 * rgbBuffer[i + 2]); } } } return cogImage; } // 将海康相机帧数据转换为CogImage24PlanarColor彩色图像 public static ICogImage ConvertToColorCogImage(IntPtr pData, ref MyCamera.MV_FRAME_OUT_INFO_EX pFrameInfo) { if (pFrameInfo.enPixelType != MvCamCtrl.NET.MyCamera.MvGvspPixelType.PixelType_Gvsp_RGB8_Packed) { throw new ArgumentException("Only RGB8 format supported for color conversion"); } CogImage24PlanarColor cogColorImage = new CogImage24PlanarColor(); int width = (int)pFrameInfo.nWidth; int height = (int)pFrameInfo.nHeight; // 分配内存 cogColorImage.Allocate(width, height); // 获取三个颜色平面指针 CogImage8Grey red = cogColorImage.GetPlane(CogImagePlaneConstants.Red); CogImage8Grey green = cogColorImage.GetPlane(CogImagePlaneConstants.Green); CogImage8Grey blue = cogColorImage.GetPlane(CogImagePlaneConstants.Blue); IntPtr redPtr = cogColorImage.GetPlane(CogImagePlaneConstants.Red).Get8GreyPixelMemory( CogImageDataModeConstants.ReadWrite, 0, 0, red.Width, red.Height).Scan0; // 获取像素数据指针 IntPtr greenPtr = cogColorImage.GetPlane(CogImagePlaneConstants.Green).Get8GreyPixelMemory( CogImageDataModeConstants.ReadWrite, 0, 0, red.Width, red.Height).Scan0; ; IntPtr bluePtr = cogColorImage.GetPlane(CogImagePlaneConstants.Blue).Get8GreyPixelMemory( CogImageDataModeConstants.ReadWrite, 0, 0, red.Width, red.Height).Scan0; ; // 转换RGB数据到平面格式 byte[] rgbBuffer = new byte[width * height * 3]; Marshal.Copy(pData, rgbBuffer, 0, rgbBuffer.Length); unsafe { byte* pRed = (byte*)redPtr.ToPointer(); byte* pGreen = (byte*)greenPtr.ToPointer(); byte* pBlue = (byte*)bluePtr.ToPointer(); for (int i = 0; i < rgbBuffer.Length; i += 3) { *pRed++ = rgbBuffer[i]; // R *pGreen++ = rgbBuffer[i + 1]; // G *pBlue++ = rgbBuffer[i + 2]; // B } } return cogColorImage; } // 使用示例(在回调函数中调用) private void ImageCallback(IntPtr pData, ref MyCamera.MV_FRAME_OUT_INFO_EX pFrameInfo, IntPtr pUser) { ICogImage resultImage; if (pFrameInfo.enPixelType == MvCamCtrl.NET.MyCamera.MvGvspPixelType.PixelType_Gvsp_Mono8) { resultImage = ConvertToCogImage(pData, ref pFrameInfo); } else { resultImage = ConvertToColorCogImage(pData, ref pFrameInfo); } Image = resultImage; } /// /// 视觉处理 /// /// private void CamVisionProCallBack(ICogImage image, TimeSpan totaltime, string errormessage) { try { cogToolBlock1.Inputs[0].Value = image; cogToolBlock1.Run(); Image = (ICogImage)cogToolBlock1.Outputs[6].Value; } finally { } } /// /// WriteableBitmap转Bitmap图像 /// /// /// public static Bitmap SafeConvert(WriteableBitmap wb) { Bitmap bmp = new Bitmap(wb.PixelWidth, wb.PixelHeight); using (var ms = new System.IO.MemoryStream()) { var encoder = new PngBitmapEncoder(); encoder.Frames.Add(BitmapFrame.Create(wb)); encoder.Save(ms); bmp = (Bitmap)System.Drawing.Image.FromStream(ms); } return bmp; } // 使用Windows API实现内存拷贝(支持重叠内存区域) [DllImport("kernel32.dll", EntryPoint = "RtlMoveMemory", SetLastError = false)] private static extern void RtlMoveMemory(IntPtr dest, IntPtr src, uint length); // 安全封装方法(带参数校验) public static void SafeMemoryCopy(IntPtr dest, IntPtr src, int byteCount) { if (dest == IntPtr.Zero || src == IntPtr.Zero) throw new ArgumentNullException("指针参数不能为null"); if (byteCount <= 0) throw new ArgumentOutOfRangeException("字节数必须大于0"); RtlMoveMemory(dest, src, (uint)byteCount); } /// /// 将WriteableBitmap转换为CogImage8Grey(自动处理彩色转灰度) /// public void OnSwitchToolBlock(int index) { cogToolBlock1 = CamTemplateS[index]; ToolBlockSwitched?.Invoke(index); // 触发事件,传递索引参数。 } /// /// 相机连接或者断开时 /// /// /// private void Management_CameraConnectChangedEvent(Guid id, bool state) { // var sta = Status.FirstOrDefault(s => s.ID == id); // var camera = DeviceConfig.Cameras.FirstOrDefault(c => c.Id == id); //if ( sta != null && camera != null ) //{ // if ( state ) // { // App.Current.Dispatcher.Invoke(new Action(() => // { // sta.Message = $"{camera.CameraName}{connected}"; // sta.Background = new SolidColorBrush(Colors.Green); // })); // } // else // { // App.Current.Dispatcher.Invoke(new Action(() => // { // sta.Message = $"{camera.CameraName}{disconnected1}"; // sta.Background = new SolidColorBrush(Colors.Red); // })); // } //} } } }