using System; using System.Collections.Generic; using System.Diagnostics; using System.Drawing; using System.IO; using System.Linq; using System.Text; using System.Threading; using System.Threading.Tasks; using System.Windows.Forms; using Extensometer.Model; using Extensometer.Model.ResultModel; using Extensometer.Model.RequestModel; using ThridLibray; namespace Extensometer.BLL { public class CameraOperationClass { #region 变量和实例 // 项目路径 public string ProjectPath = string.Empty; // 存储图像完整地址 string ImagePath; string GetObjectPath; // 图像存储变量 Bitmap bitmap = null; // 图片获取线程 bool m_bGetCamImage = true; // 相机实例 private IDevice m_dev; // 锁 public Mutex m_mutex = new Mutex(); // 存图开启标志 bool MapIsSaveLoop = false; // 相机图像缓存列表 List m_frameList = new List(); // Bitmap图像绑定时间列表 public Queue BitmapImageList = new Queue(); // Bitmap图像存图列表 public Queue SaveImageList = new Queue(); // 存图线程 Thread SaveImageThread; //取图线程 Thread GetCamImageThread; Stopwatch m_stopWatch = new Stopwatch(); //创建一个不能被外部直接调用的CameraOperationClass实例 private static readonly CameraOperationClass cameraOperationClass = new CameraOperationClass(); // 保存图片间隔标志量 private int DEFAULT_INTERVAL = 1000; #endregion #region 公共方法 /// /// 获取CameraOperaTionClass实例 /// /// public static CameraOperationClass GetCameraOperation() { return cameraOperationClass; } /// /// 获取相机像素长宽 /// /// public ResultCamSizeModel GetCamImageSize() { ResultCamSizeModel resultCamSize = new ResultCamSizeModel(); if (m_dev == null) { resultCamSize.ErrCode = ErrCodeList.CamUnLoad; resultCamSize.ErrMessage = "相机未加载"; return resultCamSize; } //获取相机像素宽 using (IIntegraParameter p = m_dev.ParameterCollection[ParametrizeNameSet.ImageWidth]) { resultCamSize.Width = p.GetValue(); } //获取相机像素高 using (IIntegraParameter p = m_dev.ParameterCollection[ParametrizeNameSet.ImageHeight]) { resultCamSize.Hight = p.GetValue(); } resultCamSize.ErrCode = ErrCodeList.Success; return resultCamSize; } /// /// 获取到设备型号 /// /// public ResultStringModel GetCamDeviceInfo_Model() { ResultStringModel result = new ResultStringModel(); try { if (m_dev != null) { result.ResultValue = m_dev.DeviceInfo.Model; result.ErrCode = ErrCodeList.Success; } else { result.ErrCode = ErrCodeList.CamUnLoad; result.ErrMessage = "未识别到已加载的相机"; } } catch (Exception e) { result.ErrCode = ErrCodeList.OtherErr; result.ErrMessage = e.ToString(); } return result; } /// /// 获取到相机曝光值 /// /// public ResultDoubleModel GetCamExposureTime() { ResultDoubleModel result = new ResultDoubleModel(); try { if (m_dev != null) { using (IFloatParameter p = m_dev.ParameterCollection[ParametrizeNameSet.ExposureTime]) { result.resultValue = p.GetValue(); } result.ErrCode = ErrCodeList.Success; } else { result.ErrCode = ErrCodeList.CamUnLoad; result.ErrMessage = "未识别到已加载的相机"; } } catch (Exception e) { result.ErrCode = ErrCodeList.OtherErr; result.ErrMessage = e.ToString(); } return result; } /// /// 获取到相机增益 /// /// public ResultDoubleModel GetCamGainRaw() { ResultDoubleModel result = new ResultDoubleModel(); try { if (m_dev != null) { using (IFloatParameter p = m_dev.ParameterCollection[ParametrizeNameSet.GainRaw]) { result.resultValue = p.GetValue(); } result.ErrCode = ErrCodeList.Success; } else { result.ErrCode = ErrCodeList.CamUnLoad; result.ErrMessage = "未识别到已加载的相机"; } } catch (Exception e) { result.ErrCode = ErrCodeList.OtherErr; result.ErrMessage = e.ToString(); } return result; } /// /// 获取到相机帧率 /// /// public ResultDoubleModel GetCamAcquisitionFrameRate() { ResultDoubleModel result = new ResultDoubleModel(); try { if (m_dev != null) { using (IFloatParameter p = m_dev.ParameterCollection[ParametrizeNameSet.AcquisitionFrameRate]) { result.resultValue = p.GetValue(); } result.ErrCode = ErrCodeList.Success; } else { result.ErrCode = ErrCodeList.CamUnLoad; result.ErrMessage = "未识别到已加载的相机"; } } catch (Exception e) { result.ErrCode = ErrCodeList.OtherErr; result.ErrMessage = e.ToString(); } return result; } /// /// 加载相机的默认状态 /// /// public ResultModel CamLoadDefault() { ResultModel result = new ResultModel(); if (m_dev != null) { try { m_dev.StreamGrabber.ImageGrabbed -= OnImageGrabbed; // 反注册回调 m_dev.ShutdownGrab(); // 停止码流 m_dev.Close(); // 关闭相机 } catch { } } Enumerator.EnumerateDevices(); m_dev = Enumerator.GetDeviceByIndex(0); //判断是否成功找到相机 if (m_dev == null) { result.ErrCode = ErrCodeList.CamUnFound; result.ErrMessage = "未找到相机"; return result; } // 注册链接事件 m_dev.CameraOpened += OnCameraOpen; m_dev.ConnectionLost += OnConnectLoss; m_dev.CameraClosed += OnCameraClose; // 打开设备 if (!m_dev.Open()) { result.ErrCode = ErrCodeList.CamOpenErr; result.ErrMessage = "相机打开失败"; return result; } //打开初始配置 //m_dev.UserSet.Current = UserSetType.userSetDefault; // 设置曝光 // set ExposureTime //using (IFloatParameter p = m_dev.ParameterCollection[ParametrizeNameSet.ExposureTime]) //{ // p.SetValue(10000); //} // 设置缓存个数为8(默认值为16) m_dev.StreamGrabber.SetBufferCount(8); // 注册码流回调事件 m_dev.StreamGrabber.ImageGrabbed += OnImageGrabbed; // 开启码流 if (!m_dev.GrabUsingGrabLoopThread()) { result.ErrCode = ErrCodeList.CamOpenGrabbingErr; result.ErrMessage = "相机码流打开失败"; return result; } result.ErrCode = ErrCodeList.Success; return result; } /// /// 加载相机的默认状态(裁剪) /// /// public ResultModel CamLoadDefault(RequestFrameCuttingModel requestFrameCutting) { ResultModel result = new ResultModel(); if (m_dev != null) { try { m_dev.StreamGrabber.ImageGrabbed -= OnImageGrabbed; // 反注册回调 m_dev.ShutdownGrab(); // 停止码流 m_dev.Close(); // 关闭相机 } catch { } } Enumerator.EnumerateDevices(); m_dev = Enumerator.GetDeviceByIndex(0); //判断是否成功找到相机 if (m_dev == null) { result.ErrCode = ErrCodeList.CamUnFound; result.ErrMessage = "未找到相机"; return result; } // 注册链接事件 m_dev.CameraOpened += OnCameraOpen; m_dev.ConnectionLost += OnConnectLoss; m_dev.CameraClosed += OnCameraClose; // 打开设备 if (!m_dev.Open()) { result.ErrCode = ErrCodeList.CamOpenErr; result.ErrMessage = "相机打开失败"; return result; } //打开初始配置 //m_dev.UserSet.Current = UserSetType.userSetDefault; using (IIntegraParameter p = m_dev.ParameterCollection[ParametrizeNameSet.ImageOffsetX]) { p.SetValue(requestFrameCutting.StartPoint.X); long b = p.GetValue(); } using (IIntegraParameter p = m_dev.ParameterCollection[ParametrizeNameSet.ImageOffsetY]) { p.SetValue(requestFrameCutting.StartPoint.Y); long b = p.GetValue(); } using (IIntegraParameter p = m_dev.ParameterCollection[ParametrizeNameSet.ImageHeight]) { p.SetValue(Math.Abs(requestFrameCutting.EndPoint.Y - requestFrameCutting.StartPoint.Y)); long a = p.GetValue(); } using (IIntegraParameter p = m_dev.ParameterCollection[ParametrizeNameSet.ImageWidth]) { p.SetValue(Math.Abs(requestFrameCutting.EndPoint.X - requestFrameCutting.StartPoint.X)); long b = p.GetValue(); } // 设置曝光 // set ExposureTime //using (IFloatParameter p = m_dev.ParameterCollection[ParametrizeNameSet.ExposureTime]) //{ // p.SetValue(10000); //} // 设置缓存个数为8(默认值为16) m_dev.StreamGrabber.SetBufferCount(8); // 注册码流回调事件 m_dev.StreamGrabber.ImageGrabbed += OnImageGrabbed; // 开启码流 if (!m_dev.GrabUsingGrabLoopThread()) { result.ErrCode = ErrCodeList.CamOpenGrabbingErr; result.ErrMessage = "相机码流打开失败"; return result; } result.ErrCode = ErrCodeList.Success; return result; } /// /// 开启或关闭图像保存(状态切换) /// /// 项目图片保存路径 /// public ResultModel StartOrStopSaveImage(string ObjectPath) { ResultModel result = new ResultModel(); try { if (string.IsNullOrEmpty(ObjectPath)) { result.ErrCode = ErrCodeList.PathEmpty; result.ErrMessage = "项目地址为空"; return result; } // 存图标志量值切换 MapIsSaveLoop = MapIsSaveLoop ? false : true; if(MapIsSaveLoop) { //初始化并运行存图线程 m_bSaveImage = true; SaveImageThread = new Thread(SaveImage); SaveImageThread.Start(); } else { m_bSaveImage = false; } GetObjectPath = ObjectPath; result.ErrCode = ErrCodeList.Success; } catch (Exception ex) { result.ErrCode = ErrCodeList.OtherErr; result.ErrMessage = ex.Message; } return result; } /// /// 相机画面裁剪 /// /// /// public ResultModel ChangeCamFrameSize(RequestFrameCuttingModel requestFrameCutting) { ResultModel result = new ResultModel(); if (m_dev != null) { try { m_dev.StreamGrabber.ImageGrabbed -= OnImageGrabbed; // 反注册回调 m_dev.ShutdownGrab(); // 停止码流 m_dev.Close(); // 关闭相机 } catch { } } Enumerator.EnumerateDevices(); m_dev = Enumerator.GetDeviceByIndex(0); // 注册链接事件 m_dev.CameraOpened += OnCameraOpen; m_dev.ConnectionLost += OnConnectLoss; m_dev.CameraClosed += OnCameraClose; // 打开设备 if (!m_dev.Open()) { result.ErrCode = ErrCodeList.CamOpenErr; result.ErrMessage = "相机打开失败"; return result; } using (IIntegraParameter p = m_dev.ParameterCollection[ParametrizeNameSet.ImageHeight]) { p.SetValue(Math.Abs(requestFrameCutting.EndPoint.Y - requestFrameCutting.StartPoint.Y)); double a = p.GetValue(); } using (IIntegraParameter p = m_dev.ParameterCollection[ParametrizeNameSet.ImageWidth]) { p.SetValue(Math.Abs(requestFrameCutting.EndPoint.X - requestFrameCutting.StartPoint.X)); double a = p.GetValue(); } using (IIntegraParameter p = m_dev.ParameterCollection[ParametrizeNameSet.ImageOffsetX]) { p.SetValue(requestFrameCutting.StartPoint.X); double a = p.GetValue(); } using (IIntegraParameter p = m_dev.ParameterCollection[ParametrizeNameSet.ImageOffsetY]) { p.SetValue(requestFrameCutting.StartPoint.Y); double a = p.GetValue(); } m_dev.StreamGrabber.SetBufferCount(8); // 注册码流回调事件 m_dev.StreamGrabber.ImageGrabbed += OnImageGrabbed; // 开启码流 if (!m_dev.GrabUsingGrabLoopThread()) { result.ErrCode = ErrCodeList.CamOpenGrabbingErr; result.ErrMessage = "相机码流打开失败"; return result; } result.ErrCode = ErrCodeList.Success; return result; } /// /// 修改相机Gain值 /// /// /// public ResultModel ChangeCamGain(int GainValue) { ResultModel result = new ResultModel(); if (!(GainValue >= 1 && GainValue <= 32)) { result.ErrCode = ErrCodeList.ValueRangeErr; result.ErrMessage = "输入值范围异常"; return result; } if (m_dev != null) { try { m_dev.StreamGrabber.ImageGrabbed -= OnImageGrabbed; // 反注册回调 m_dev.ShutdownGrab(); // 停止码流 m_dev.Close(); // 关闭相机 } catch { } } Enumerator.EnumerateDevices(); m_dev = Enumerator.GetDeviceByIndex(0); // 注册链接事件 m_dev.CameraOpened += OnCameraOpen; m_dev.ConnectionLost += OnConnectLoss; m_dev.CameraClosed += OnCameraClose; // 打开设备 if (!m_dev.Open()) { result.ErrCode = ErrCodeList.CamOpenErr; result.ErrMessage = "相机打开失败"; return result; } using (IFloatParameter p = m_dev.ParameterCollection[ParametrizeNameSet.GainRaw]) { p.SetValue(GainValue); } m_dev.StreamGrabber.SetBufferCount(8); // 注册码流回调事件 m_dev.StreamGrabber.ImageGrabbed += OnImageGrabbed; // 开启码流 if (!m_dev.GrabUsingGrabLoopThread()) { result.ErrCode = ErrCodeList.CamOpenGrabbingErr; result.ErrMessage = "相机码流打开失败"; return result; } result.ErrCode = ErrCodeList.Success; return result; } /// /// 修改相机ExposureTime值 /// /// /// public ResultModel ChangeCamExposureTime(int ExposureTimeValue) { ResultModel result = new ResultModel(); if (ExposureTimeValue < 16) { result.ErrCode = ErrCodeList.ValueRangeErr; result.ErrMessage = "输入值范围异常"; return result; } if (m_dev != null) { try { m_dev.StreamGrabber.ImageGrabbed -= OnImageGrabbed; // 反注册回调 m_dev.ShutdownGrab(); // 停止码流 m_dev.Close(); // 关闭相机 } catch { } } Enumerator.EnumerateDevices(); m_dev = Enumerator.GetDeviceByIndex(0); // 注册链接事件 m_dev.CameraOpened += OnCameraOpen; m_dev.ConnectionLost += OnConnectLoss; m_dev.CameraClosed += OnCameraClose; // 打开设备 if (!m_dev.Open()) { result.ErrCode = ErrCodeList.CamOpenErr; result.ErrMessage = "相机打开失败"; return result; } using (IFloatParameter p = m_dev.ParameterCollection[ParametrizeNameSet.ExposureTime]) { p.SetValue(ExposureTimeValue); } m_dev.StreamGrabber.SetBufferCount(8); // 注册码流回调事件 m_dev.StreamGrabber.ImageGrabbed += OnImageGrabbed; // 开启码流 if (!m_dev.GrabUsingGrabLoopThread()) { result.ErrCode = ErrCodeList.CamOpenGrabbingErr; result.ErrMessage = "相机码流打开失败"; return result; } result.ErrCode = ErrCodeList.Success; return result; } /// /// 修改采样帧率 /// /// /// public ResultModel ChangeCamAcquisitionFrameRate(int AcquisitionFrameRateValue) { ResultModel result = new ResultModel(); if (AcquisitionFrameRateValue < 1 || AcquisitionFrameRateValue > 2000) { result.ErrCode = ErrCodeList.ValueRangeErr; result.ErrMessage = "输入值范围异常"; return result; } if (m_dev != null) { try { m_dev.StreamGrabber.ImageGrabbed -= OnImageGrabbed; // 反注册回调 m_dev.ShutdownGrab(); // 停止码流 m_dev.Close(); // 关闭相机 } catch { } } Enumerator.EnumerateDevices(); m_dev = Enumerator.GetDeviceByIndex(0); // 注册链接事件 m_dev.CameraOpened += OnCameraOpen; m_dev.ConnectionLost += OnConnectLoss; m_dev.CameraClosed += OnCameraClose; // 打开设备 if (!m_dev.Open()) { result.ErrCode = ErrCodeList.CamOpenErr; result.ErrMessage = "相机打开失败"; return result; } using (IBooleanParameter p = m_dev.ParameterCollection[ParametrizeNameSet.AcquisitionFrameRateEnable]) { p.SetValue(true); } using (IFloatParameter p = m_dev.ParameterCollection[ParametrizeNameSet.AcquisitionFrameRate]) { p.SetValue(AcquisitionFrameRateValue); } m_dev.StreamGrabber.SetBufferCount(8); // 注册码流回调事件 m_dev.StreamGrabber.ImageGrabbed += OnImageGrabbed; // 开启码流 if (!m_dev.GrabUsingGrabLoopThread()) { result.ErrCode = ErrCodeList.CamOpenGrabbingErr; result.ErrMessage = "相机码流打开失败"; return result; } result.ErrCode = ErrCodeList.Success; return result; } /// /// 关闭相机 /// /// public ResultModel CloseCam() { ResultModel resultModel = new ResultModel(); m_dev.Close(); return resultModel; } /// /// 查询存图状态 /// /// /// true:存图开启 /// false: 存图关闭 /// public bool IsStartSaveImage() { return MapIsSaveLoop; } public void ChangSaveImageSpacing(RequestFromConfigModel ReadFromConfig) { if(ReadFromConfig.ImageSaveModel==ImageSaveModel.AllSave) { DEFAULT_INTERVAL = 0; } else if(ReadFromConfig.ImageSaveModel==ImageSaveModel.SpacingSave) { DEFAULT_INTERVAL = ReadFromConfig.SpacingSaveImageTime; } } #endregion #region 私有方法 /// /// 初始化CameraOperationClass /// private CameraOperationClass() { GetCamImageThread = new Thread(GetCamImage); GetCamImageThread.Start(); } // 码流数据回调 private void OnImageGrabbed(Object sender, GrabbedEventArgs e) { m_mutex.WaitOne(); m_frameList.Add(e.GrabResult.Clone()); m_mutex.ReleaseMutex(); } // 相机打开回调 private void OnCameraOpen(object sender, EventArgs e) { } // 相机关闭回调 private void OnCameraClose(object sender, EventArgs e) { } // 相机丢失回调 private void OnConnectLoss(object sender, EventArgs e) { m_dev.ShutdownGrab(); m_dev.Dispose(); m_dev = null; } /// /// 主动回收内存 /// private void UserMemoryCollect() { GC.Collect(); GC.WaitForPendingFinalizers(); } /// /// 判断是否执行保存操作(帧率限制) /// /// private bool isTimeToDisplay() { m_stopWatch.Stop(); long m_lDisplayInterval = m_stopWatch.ElapsedMilliseconds; if (m_lDisplayInterval <= DEFAULT_INTERVAL) { m_stopWatch.Start(); return false; } else { m_stopWatch.Reset(); m_stopWatch.Start(); return true; } } #endregion #region 线程方法 // 存图线程控制变量 private bool m_bSaveImage = false; /// /// 存图线程 /// private void SaveImage() { TimeImageClass frame = new TimeImageClass(); while (m_bSaveImage) { if (SaveImageList.Count == 0) { Thread.Sleep(10); continue; } // 图像队列取最新帧 //m_mutex.WaitOne(); frame = SaveImageList.Dequeue(); //m_mutex.ReleaseMutex(); // 判断是否开启存图 if (!MapIsSaveLoop) { continue; } // 存图间隔限制 if (!isTimeToDisplay()) { continue; } // 主动调用回收垃圾 UserMemoryCollect(); if (!Directory.Exists(GetObjectPath)) { Directory.CreateDirectory(GetObjectPath); continue; } ImagePath = GetObjectPath + "\\" + frame.ImageDateTime.ToString("yyyyMMddHHmmssff") + ".bmp"; frame.ImageBitMap.Save(ImagePath, System.Drawing.Imaging.ImageFormat.Bmp); } } /// /// 从相机获取图像并处理 /// private void GetCamImage() { TimeImageClass timeToImage = new TimeImageClass(); while (m_bGetCamImage) { if (m_frameList.Count == 0) { Thread.Sleep(10); continue; } // 图像队列取最新帧 m_mutex.WaitOne(); IGrabbedRawData frame = m_frameList.ElementAt(0); if (m_frameList.Count > 10) { LOG.error("GetCamImage-m_frameList数据异常抛出,帧丢弃"); m_frameList.Clear(); } else m_frameList.Remove(frame); //m_frameList.Remove(frame); m_mutex.ReleaseMutex(); // 主动调用回收垃圾 UserMemoryCollect(); try { lock(this) { timeToImage = new TimeImageClass() { ImageBitMap = frame.ToBitmap(false), ImageByte = frame.Image, ImageDateTime = DateTime.Now }; // 向相机操作类中的待处理列表添加数据 BitmapImageList.Enqueue(timeToImage); } } catch { } } } #endregion } }