using CCDCount.MODEL.CameraClass; using CCDCount.MODEL.ConfigModel; using LogClass; using MvCameraControl; using System; using System.Collections.Concurrent; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using System.Runtime.InteropServices; using System.Threading; namespace CCDCount.DLL { public class CameraClass { #region 常量 readonly DeviceTLayerType enumTLayerType = DeviceTLayerType.MvGigEDevice | DeviceTLayerType.MvUsbDevice | DeviceTLayerType.MvGenTLGigEDevice | DeviceTLayerType.MvGenTLCXPDevice | DeviceTLayerType.MvGenTLCameraLinkDevice | DeviceTLayerType.MvGenTLXoFDevice; #endregion #region 变量 private List CamList; // 相机列表 private IDevice device = null; // 相机实例 private Thread receiveThread = null; // 接收图像线程 private ConcurrentQueue FrameOuts = new ConcurrentQueue(); private ConcurrentQueue ImageBytes = new ConcurrentQueue(); //图像接受队列 private int OnImageSelectRows = 20; private long lastframeNum = -1; public int CamereNo { get { return _cameraNo; } } public int ImageNum { get { return FrameOuts.Count; }} private int _cameraNo = -1; private string cameraName = string.Empty; #endregion #region 公共方法 /// /// 获取相机列表 /// /// /// public void GetCameraList(out List CameraInfoList) { CamList = new List(); CameraInfoList = new List(); int nRet = DeviceEnumerator.EnumDevices(enumTLayerType, out CamList); if (nRet != MvError.MV_OK) { return; } else { //输出相机名称及SN码以方便选择设备 foreach (var item in CamList) { CameraInfoList.Add(new CameraInfoClass { //DeviceName = item.UserDefinedName == "" ? item.ModelName : item.UserDefinedName, DeviceName = item.ModelName, DeviceSN = item.SerialNumber, }); } } return; } /// /// 更新相机列表 /// public void UpdateCameraList() { CamList = new List(); int nRet = DeviceEnumerator.EnumDevices(enumTLayerType, out CamList); if (nRet != MvError.MV_OK) { Console.WriteLine("相机列表更新失败"); return; } } /// /// 加载指定相机 /// /// public bool LoadCamereDevice(CameraConfig DeviceConfig) { bool Blresult = false; List deviceInfos = CamList.Where(o => o.SerialNumber == DeviceConfig.CameraSNNum).ToList(); if(deviceInfos.Count == 0) return Blresult; IDeviceInfo deviceInfo = deviceInfos.First(); try { // 打开设备 device = DeviceFactory.CreateDevice(deviceInfo); } catch (Exception ex) { LOG.error("Create Device fail!" + ex.Message); return Blresult; } int result = device.Open(); if (result != MvError.MV_OK) { LOG.error("Open Device fail!" + result); return Blresult; } // 判断是否为gige设备 if (device is IGigEDevice) { // 转换为gigE设备 IGigEDevice gigEDevice = device as IGigEDevice; // 探测网络最佳包大小(只对GigE相机有效) int optionPacketSize; result = gigEDevice.GetOptimalPacketSize(out optionPacketSize); if (result != MvError.MV_OK) { //Log("Warning: Get Packet Size failed!", result); } else { result = device.Parameters.SetIntValue("GevSCPSPacketSize", (long)optionPacketSize); if (result != MvError.MV_OK) { //Log("Warning: Set Packet Size failed!", result); } } } //判断是否从配置文件读取的参数,是则设置参数,否则加载相机默认参数 if(DeviceConfig.IsLoadCanfig) { //设置从配置文件读取的参数 device.Parameters.GetStringValue("DeviceModelName", out IStringValue deviceModelName); _cameraNo = DeviceConfig.CamerNo; if (DeviceConfig.CameraName != deviceModelName.CurValue) device.Parameters.SetStringValue("DeviceUserID", DeviceConfig.CameraName); device.Parameters.SetFloatValue("ExposureTime", DeviceConfig.ExposureTimeValue); device.Parameters.SetIntValue("AcquisitionLineRate", DeviceConfig.AcquistionLineRateValue); device.Parameters.SetIntValue("Height", DeviceConfig.Height); device.Parameters.SetIntValue("Width", DeviceConfig.Width); device.Parameters.SetIntValue("OffsetX", DeviceConfig.OffsetX); } // 设置采集连续模式 device.Parameters.SetEnumValueByString("AcquisitionMode", "Continuous"); device.Parameters.SetEnumValueByString("TriggerMode", "Off"); Blresult = true; return Blresult; } /// /// 重新加载指定相机 /// /// /// public bool ReLoadCameraDevice(string CameraSN) { bool Blresult = false; if(device!=null && device.IsConnected) { device.Close(); device.Dispose(); } UpdateCameraList(); List deviceInfos = CamList.Where(o => o.SerialNumber == CameraSN).ToList(); if (deviceInfos.Count == 0) return Blresult; IDeviceInfo deviceInfo = deviceInfos.First(); try { // 打开设备 device = DeviceFactory.CreateDevice(deviceInfo); Blresult = true; } catch (Exception ex) { LOG.error("Create Device fail!" + ex.Message); return Blresult; } int result = device.Open(); if (result != MvError.MV_OK) { Blresult = false; LOG.error("Open Device fail!" + result); return Blresult; } // 判断是否为gige设备 if (device is IGigEDevice) { // 转换为gigE设备 IGigEDevice gigEDevice = device as IGigEDevice; // 探测网络最佳包大小(只对GigE相机有效) int optionPacketSize; result = gigEDevice.GetOptimalPacketSize(out optionPacketSize); if (result != MvError.MV_OK) { //Log("Warning: Get Packet Size failed!", result); } else { result = device.Parameters.SetIntValue("GevSCPSPacketSize", (long)optionPacketSize); if (result != MvError.MV_OK) { //Log("Warning: Set Packet Size failed!", result); } } } return Blresult; } /// /// 开启相机采集 /// public void StartCamera() { StartReceiveFuntion(); } /// /// 关闭相机采集 /// public void StopCamera() { StopReceiveFuntion(); //StopEventGetImage(); if(device!=null) { int result = device.StreamGrabber.StopGrabbing(); device.Close(); device.Dispose(); if (result != MvError.MV_OK) { LOG.log(("Stop Grabbing Fail!", result)); } } } public bool GetOnceImage(out IFrameOut IFrameData) { bool result = false; int BRet = device.StreamGrabber.GetImageBuffer(1000, out IFrameData); if (BRet == 0 && IFrameData != null) result = true; else return result; if (lastframeNum == -1) { lastframeNum = IFrameData.FrameNum; } else if (lastframeNum == IFrameData.FrameNum - 1) { lastframeNum = IFrameData.FrameNum; } else { //丢帧记录 LOG.log(string.Format("lost frame: Width[{0}] , Height[{1}] , FrameNum[{2}] ,Frevous[{3}]", IFrameData.Image.Width, IFrameData.Image.Height, IFrameData.FrameNum - 1, lastframeNum), 6); Console.WriteLine("lost frame: Width[{0}] , Height[{1}] , FrameNum[{2}] ,Frevous[{3}]", IFrameData.Image.Width, IFrameData.Image.Height, IFrameData.FrameNum - 1, lastframeNum); lastframeNum = IFrameData.FrameNum; } return result; } /// /// 获取相机图像尺寸信息 /// /// public CameraImageSizeClass GetCamereImageSize() { CameraImageSizeClass cameraImageSize =new CameraImageSizeClass(); IIntValue PixWidth; IIntValue PixHeight; device.Parameters.GetIntValue("Width", out PixWidth); device.Parameters.GetIntValue("Height", out PixHeight); cameraImageSize.Height = (int)PixHeight.CurValue; cameraImageSize.Width = (int)PixWidth.CurValue; return cameraImageSize; } /// /// 获取Config信息 /// /// public CameraConfig GetConfigValue() { CameraConfig result = null; device.Parameters.GetFloatValue("ExposureTime", out IFloatValue exposureTime); device.Parameters.GetIntValue("AcquisitionLineRate", out IIntValue acquisitionLineRate); device.Parameters.GetIntValue("OffsetX", out IIntValue offsetX); device.Parameters.GetIntValue("Height", out IIntValue pixHeight); device.Parameters.GetIntValue("Width", out IIntValue pixWidth); device.Parameters.GetStringValue("DeviceUserID", out IStringValue deviceUserID); device.Parameters.GetStringValue("DeviceModelName", out IStringValue deviceModelName); device.Parameters.GetStringValue("DeviceSerialNumber", out IStringValue deviceSerialNumber); result = new CameraConfig() { CameraSNNum = deviceSerialNumber.CurValue, ExposureTimeValue = exposureTime.CurValue, AcquistionLineRateValue = (int)acquisitionLineRate.CurValue, Height = (int)pixHeight.CurValue, Width = (int)pixWidth.CurValue, OffsetX = (int)offsetX.CurValue, CameraName = deviceUserID.CurValue, DeviceName = deviceModelName.CurValue, CamerNo = _cameraNo }; return result; } /// /// 保存参数 /// public void SaveConfig() { CameraConfig camerasConfig = null; if (!Directory.Exists(".\\Config\\")) Directory.CreateDirectory(".\\Config\\"); XmlStorage.SerializeToXml(camerasConfig, ".\\Config\\CameraConfig.xml"); } public bool IsLoadCamera() { return device == null ? false : true; } public bool IsConnectCamera() { if (device == null) return false; else { return device.IsConnected; } } #endregion #region 私有方法 /// /// 开启采集 /// private void StartReceiveFuntion() { try { device.StreamGrabber.SetImageNodeNum(100); device.StreamGrabber.StartGrabbing(); } catch (Exception ex) { LOG.error("Start thread failed!, " + ex.Message); throw; } } /// /// 关闭采集 /// private void StopReceiveFuntion() { try { if (device == null) return; int ret = device.StreamGrabber.StopGrabbing(); if (ret != MvError.MV_OK) { LOG.error(("Stop grabbing failed:{0:x8}", ret)); return; } } catch (Exception ex) { LOG.error("Stop thread failed!, " + ex.Message); throw; } } /// /// 读取图像像素信息(单行) /// /// 帧数据 /// private byte[] GetImageFristRowsData(IFrameOut frameOut) { //创建 byte[] PixelData = new byte[(int)frameOut.Image.Width]; //从相机缓存中拷贝出图像数据 Marshal.Copy(frameOut.Image.PixelDataPtr, PixelData, 0, (int)frameOut.Image.Width); return PixelData; } /// /// 读取图像像素信息(多行) /// /// /// private Queue GetImageRowsData(IFrameOut frameOut) { //创建 Queue PixelDatas = new Queue(); for (int i = 0;i< OnImageSelectRows;i++) //for (int i = 0;i< frameOut.Image.Height;i++) { byte[] PixelData = new byte[frameOut.Image.Width]; Marshal.Copy(IntPtr.Add(frameOut.Image.PixelDataPtr,i * (int)frameOut.Image.Width), PixelData, 0, (int)frameOut.Image.Width); PixelDatas.Enqueue(PixelData.Clone() as byte[]); PixelData = null; } return PixelDatas; } #endregion } }