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 static Cognex.VisionPro.QuickBuild.CogJobManager; 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; 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() { List listsn = CameraService.GetDeviceEnum(); if ( listsn.Count > 0 ) { ObservableCollection strings=new ObservableCollection(); for ( int i = 0; i < listsn.Count; 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); // })); // } //} } } }