using CCDCount.MODEL.CameraClass; using CCDCount.MODEL.ConfigModel; using CCDCount.MODEL.ShuLiClass; using LogClass; using MvCameraControl; using System; using System.Collections.Generic; using System.Diagnostics; using System.Drawing; using System.IO; using System.Linq; using System.Runtime.Remoting.Messaging; using System.Threading; namespace CCDCount.DLL { public class MainThreadClass { #region 变量与实例 Thread SwitchIdentifyImageThread = null; bool IsSwitch = false; public ShuLiClass shuLiClass = null; CameraClass cameraClass = new CameraClass(); public string ThisCameraDevice = string.Empty; public string ThisCameraSN = string.Empty; public string ThisCamerName = string.Empty; public int ThisCamerNo = -1; //留给主界面的回调函数 public event EventHandler WorkerToFrom; public bool CameraStatic { get { return _CameraStatic; } } private bool _CameraStatic = false; public bool CameraRunStatic { get { return cameraClass.IsGrabbing; } } public bool IsOpenLoadThread { get { return _IsOpenLoadThread; }} private bool _IsOpenLoadThread = false; public int HistoryActiveNum { get { return shuLiClass.GetHistoryActiveNum(); } } public int OkHistoryNum { get { return shuLiClass.GetOkHistoryNum(); } } public int NgHistoryNum { get { return shuLiClass.GetNgHistoryNum(); } } ZmcauxClass zmcauxClass = new ZmcauxClass(); //private BottingClass Botting = new BottingClass(); //private MechanicalControlClass MechanicalControl = new MechanicalControlClass(); /// /// 数粒状态计时器 /// Stopwatch stopwatch = Stopwatch.StartNew(); /// /// 数粒状态 /// private bool _ShuLiState = true; public bool ShuLiState { get { return _ShuLiState; } } #endregion #region 公共方法 public MainThreadClass(ShuLiConfigClass configClass,CameraConfig CameraConfig) { // 数粒配置文件地址 if (configClass!=null) { // 创建数粒对象(配置文件) shuLiClass = new ShuLiClass(configClass); } else { // 创建数粒对象(默认) shuLiClass = new ShuLiClass(); } _IsOpenLoadThread = CameraConfig.IsOpenLoad; ThisCameraSN = CameraConfig.CameraSNNum; ThisCamerName = CameraConfig.CameraName; ThisCameraDevice = CameraConfig.DeviceName; ThisCamerNo = CameraConfig.CamerNo; } /// /// 开始主线程 /// public bool StartMianThread(CameraConfig DeviceConfig) { bool result = false; // 相机列表 List list = new List(); // 获取相机列表 cameraClass.GetCameraList(out list); if (list.Count == 0) { LOG.error(string.Format("{0}:没有相机", "MainThreadClass-StartMianThread")); // 如果没有相机,则退出 return result; } // 加载相机 // cameraClass.LoadCamereDevice(list.First().DeviceSN); if(!cameraClass.LoadCamereDevice(DeviceConfig)) { LOG.error(string.Format("{0}:相机加载失败", "MainThreadClass-StartMianThread")); return result; } // 取图线程开启 cameraClass.StartCamera(); _CameraStatic = true; // 数据交换线程开启 StartSwitchThread(); // 为数粒算法的识别成功一粒回调函数添加方法 shuLiClass.WorkCompleted += Worker_OneGrainCompleted; // 开启识别线程 shuLiClass.StartIdentifyFuntion(cameraClass.GetCamereImageSize().Width); zmcauxClass.OpenZmcauxCard(); result = true; return result; } /// /// 开始主线程 /// public bool StartMianThread() { bool result = false; // 相机列表 List list = new List(); // 获取相机列表 cameraClass.GetCameraList(out list); if (list.Count == 0) { // 如果没有相机,则退出 return result; } // 为数粒算法的识别成功一粒回调函数添加方法 shuLiClass.WorkCompleted += Worker_OneGrainCompleted; // 加载相机 if (!cameraClass.LoadCamereDevice(new CameraConfig() { CameraSNNum = list.First().DeviceSN})) return result; _CameraStatic = true; // 取图线程开启 cameraClass.StartCamera(); // 数据交换线程开启 StartSwitchThread(); // 开启识别线程 shuLiClass.StartIdentifyFuntion(cameraClass.GetCamereImageSize().Width); zmcauxClass.OpenZmcauxCard(); result = true; return result; } /// /// 停止主线程 /// public void StopMianThread() { shuLiClass.WorkCompleted -= Worker_OneGrainCompleted; // 相机取图线程关闭 cameraClass.StopCamera(); // 数据交换线程关闭 StopSwitchThread(); // 数粒识别线程关闭 shuLiClass.StopIdentifyFuntion(); zmcauxClass.CloseZmcauxCard(); } public bool ReLoadCamera(string CameraSN) { bool result = false; result = cameraClass.ReLoadCameraDevice(CameraSN); if (result) { CameraConfig ReloadCaonfig = cameraClass.GetConfigValue(); ThisCameraSN = ReloadCaonfig.CameraSNNum; ThisCamerName = ReloadCaonfig.CameraName; ThisCameraDevice = ReloadCaonfig.DeviceName; } return result; } public void DisposeCamera() { cameraClass.StopCamera(); ThisCameraSN = string.Empty; ThisCamerName = string.Empty; ThisCameraDevice = string.Empty; } /// /// 获取显示用的图片数据 /// /// /// public void GetShowImage(int ImageHeight,out Bitmap ImageData) { List RowsShowList = new List(); ActiveObjectClass NewActive = shuLiClass.GetLastActive(); if (NewActive == null) { LOG.log(string.Format("{0}:没有获取到数粒数据", "MainThreadClass-GetShowImage")); ImageData = null; return; } List Data = shuLiClass.GetHistoryActive().Where(o => o.LastSeenLine > NewActive.LastSeenLine - ImageHeight).ToList(); Data.ForEach(o => o.RowsData.ForEach(p => RowsShowList.Add(p))); Bitmap BitmapImage = new Bitmap(NewActive.ImageWidth, ImageHeight); Graphics g = Graphics.FromImage(BitmapImage); Pen redPen = new Pen(Color.Red, 1); List ShowList = RowsShowList.Where(o => o.RowsCol > NewActive.LastSeenLine - BitmapImage.Height).ToList(); RowsShowList.Where(o => o.RowsCol < NewActive.LastSeenLine - BitmapImage.Height).ToList().ForEach(o => RowsShowList.Remove(o)); RowsShowList.Clear(); ShowList.ForEach(o => g.DrawLine(redPen, new Point(o.StartCol, (int)(NewActive.LastSeenLine - o.RowsCol)), new Point(o.EndCol, (int)(NewActive.LastSeenLine - o.RowsCol)))); ShowList.Clear(); ImageData = BitmapImage.Clone() as Bitmap; BitmapImage.Dispose(); //GC.Collect(); } /// /// 获取此刻的Config数据 /// /// public void GetConfigValue(out CameraConfig Camconfig,out ShuLiConfigClass shuLiConfig) { //判断是否加载了相机 if(cameraClass.IsLoadCamera()) //获取已经加载的相机的配置 Camconfig = cameraClass.GetConfigValue(); else //新建一个相机配置 Camconfig = new CameraConfig(); //读取视觉配置 shuLiConfig = shuLiClass.GetConfigValue(); } /// /// 获取相机此刻的Config数据 /// /// public void GetCameraConfig(out CameraConfig CameraConfig) { //判断是否加载了相机 if (cameraClass.IsLoadCamera()) //获取已经加载的相机的配置 CameraConfig = cameraClass.GetConfigValue(); else //新建一个相机配置 CameraConfig = new CameraConfig(); } /// /// 保存所有Config /// public void SaveAllConfig() { shuLiClass.SaveConfig(); } /// /// 获取相机连接状态 /// /// public bool GetCameraConnectStatic() { bool result = false; if(cameraClass != null) result = cameraClass.IsConnectCamera(); return result; } public void Dispose() { //MechanicalControl.Dispose(); } #endregion #region 私有方法 //bool IsFill = false; //bool IsXuanZhuanCloseFaMen = false; /// /// 每数完一粒识别线程执行的事件 /// /// /// private void Worker_OneGrainCompleted(object sender, ActiveObjectEventArgsClass e) { LOG.log("有活跃物体转换为了历史物体,回调事件被触发!",6); if (e.Actives.Where(o => o.StateCode == 7).Count() > 0) { stopwatch.Restart(); _ShuLiState = false; } else if (stopwatch.ElapsedMilliseconds > 1000) { stopwatch.Stop(); _ShuLiState = true; } foreach (ActiveObjectClass oneActive in e.Actives) { LOG.log(string.Format("输出当前颗粒信息,开始行:{0},结束行:{1},开始时间:{2}结束时间:{3},颗粒状态:{4}", oneActive.StartLine, oneActive.LastSeenLine, oneActive.StartCheckTime.ToString("O"), oneActive.EndCheckTime.ToString("O"), oneActive.StateCode), 6); } // 事件处理逻辑 float step = -1; float[] floats = new float[9]; zmcauxClass.GetMessageFromVar("countStep", ref step); LOG.log(string.Format("{0}:countStep = {1}", "MainThreadClass-Worker_OneGrainCompleted", step),6); if (step < 1 || step>3) { zmcauxClass.GetMessageFromArray("CCD_DATA4", ref floats, 0, 9); } else { switch (step) { case 1: zmcauxClass.GetMessageFromArray("CCD_DATA1", ref floats, 0, 9); break; case 2: zmcauxClass.GetMessageFromArray("CCD_DATA2", ref floats, 0, 9); break; case 3: zmcauxClass.GetMessageFromArray("CCD_DATA3", ref floats, 0, 9); break; } } LOG.log("读取轴卡结果数据:" + floats[0] + " " + floats[1] + " " + floats[2] + " " + floats[3] + " " + floats[4] + " " + floats[5] + " " + floats[6] + " " + floats[7] + " " + floats[8],6); foreach (ActiveObjectClass oneActive in e.Actives) { if (oneActive.StateCode != 0) { floats[8] += 1; } else { if (oneActive.ChannelNO != -1) floats[oneActive.ChannelNO] += 1; else floats[8] += 1; } } LOG.log("写入轴卡结果数据:" + floats[0] + " " + floats[1] + " " + floats[2] + " " + floats[3] + " " + floats[4] + " " + floats[5] + " " + floats[6] + " " + floats[7] + " " + floats[8],6); if (step < 1 || step>3) { zmcauxClass.SetMessageToArray("CCD_DATA4", floats, 0, 9); } else { switch (step) { case 1: zmcauxClass.SetMessageToArray("CCD_DATA1", floats, 0, 9); break; case 2: zmcauxClass.SetMessageToArray("CCD_DATA2", floats, 0, 9); break; case 3: zmcauxClass.SetMessageToArray("CCD_DATA3", floats, 0, 9); break; } } //OnOneGrain(e.Actives); } /// /// 装瓶逻辑 /// private void BottLogicFunction() { } /// /// 对外通知事件 /// private void OnOneGrain(List activeObject) { ActiveObjectEventArgsClass activeObjectEventArgs = new ActiveObjectEventArgsClass(activeObject); // 触发事件 WorkerToFrom?.Invoke(this, activeObjectEventArgs); } #endregion #region 线程方法 /// /// 开启交换线程 /// private void StartSwitchThread() { IsSwitch = true; SwitchIdentifyImageThread = new Thread(SwitchIdentifyImageProcess); SwitchIdentifyImageThread.Start(); } /// /// 关闭交换线程 /// private void StopSwitchThread() { try { // 标志位设为false IsSwitch = false; if (SwitchIdentifyImageThread != null && SwitchIdentifyImageThread.IsAlive) SwitchIdentifyImageThread.Join(); } catch (Exception ex) { LOG.error("Start thread failed!, " + ex.Message); throw; } } /// /// 交换线程 /// private void SwitchIdentifyImageProcess() { IFrameOut IFramedata = null; Stopwatch stopwatch = Stopwatch.StartNew(); stopwatch.Start(); while (IsSwitch) { if (stopwatch.ElapsedMilliseconds > 1000) { Console.WriteLine("交换线程-相机获取实例中的图像缓存队列长度:{0}", cameraClass.ImageNum); Console.WriteLine("交换线程-图像处理实例中的待识别图像缓存队列长度{0}", shuLiClass.ImageNum); GC.Collect(); stopwatch.Restart(); } //Thread.Sleep(5); bool result = cameraClass.GetOnceImage(out IFramedata); if (result) { if (IFramedata == null) continue; shuLiClass.SetOnceIdentifyImageData(IFramedata); } else continue; IFramedata.Dispose(); } stopwatch.Stop(); } #endregion } }