123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613 |
- 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<IDeviceInfo> CamList; // 相机列表
- private IDevice device = null; // 相机实例
- public bool IsGrabbing { get { return _isGrabbing; }}
- private bool _isGrabbing = false; // 是否正在取图
- private Thread receiveThread = null; // 接收图像线程
- private ConcurrentQueue<IFrameOut> FrameOuts = new ConcurrentQueue<IFrameOut>();
- private ConcurrentQueue<byte[]> ImageBytes = new ConcurrentQueue<byte[]>(); //图像接受队列
- 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 公共方法
- /// <summary>
- /// 获取相机列表
- /// </summary>
- /// <param name="CamList"></param>
- /// <returns></returns>
- public void GetCameraList(out List<CameraInfoClass> CameraInfoList)
- {
- CamList = new List<IDeviceInfo>();
- CameraInfoList = new List<CameraInfoClass>();
- 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;
- }
- /// <summary>
- /// 更新相机列表
- /// </summary>
- public void UpdateCameraList()
- {
- CamList = new List<IDeviceInfo>();
- int nRet = DeviceEnumerator.EnumDevices(enumTLayerType, out CamList);
- if (nRet != MvError.MV_OK)
- {
- Console.WriteLine("相机列表更新失败");
- return;
- }
- }
- /// <summary>
- /// 加载指定相机
- /// </summary>
- /// <param name="DeviceSN"></param>
- public bool LoadCamereDevice(CameraConfig DeviceConfig)
- {
- bool Blresult = false;
- List<IDeviceInfo> 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;
- }
- /// <summary>
- /// 重新加载指定相机
- /// </summary>
- /// <param name="CameraSN"></param>
- /// <returns></returns>
- public bool ReLoadCameraDevice(string CameraSN)
- {
- bool Blresult = false;
- if(device!=null && device.IsConnected)
- {
- device.Close();
- device.Dispose();
- }
- UpdateCameraList();
- List<IDeviceInfo> 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;
- }
- /// <summary>
- /// 开启相机采集
- /// </summary>
- public void StartCamera()
- {
- //StartEventGetImage();
- StartReceiveFuntion();
- //StartImageRowsDataFuntion();
- // 开始采集
- if (!_isGrabbing)
- {
- _isGrabbing = false;
- receiveThread.Join();
- LOG.log(string.Format("{0}:采集线程开启失败", "CameraClass-StartCamera"));
- return;
- }
- }
- /// <summary>
- /// 关闭相机采集
- /// </summary>
- public void StopCamera()
- {
- StopReceiveAndImageRowsDataFuntion();
- //StopEventGetImage();
- if(device!=null)
- {
- int result = device.StreamGrabber.StopGrabbing();
- device.Close();
- device.Dispose();
- if (result != MvError.MV_OK)
- {
- LOG.log(("Stop Grabbing Fail!", result));
- }
- }
- }
- /// <summary>
- /// 获取第一张缓存中的图像,并把这个图像从缓存中清楚
- /// </summary>
- /// <param name="ImageData"></param>
- public bool GetOnceImage(out byte[] ImageData)
- {
- bool result = false;
- //初始化图像数据
- ImageData = null;
- //判断是否可以给图像数据赋值
- if(ImageBytes.Count()!=0)
- {
- ImageData = new byte[ImageBytes.Last().Count()];
- ImageBytes.TryDequeue(out ImageData);
- result = true;
- }
- return result;
- }
- public bool GetOnceImage(out IFrameOut IFrameData)
- {
- bool result = false;
- //初始化图像数据
- IFrameData = null;
- //判断是否可以给图像数据赋值
- if (FrameOuts.Count() != 0)
- {
- FrameOuts.TryDequeue(out IFrameData);
- result = true;
- }
- return result;
- }
- /// <summary>
- /// 获取相机图像尺寸信息
- /// </summary>
- /// <returns></returns>
- 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;
- }
- /// <summary>
- /// 获取Config信息
- /// </summary>
- /// <returns></returns>
- 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;
- }
- /// <summary>
- /// 保存参数
- /// </summary>
- 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 私有方法
- /// <summary>
- /// 图像分割线程
- /// </summary>
- private void ImageRowsDataProcess()
- {
- IFrameOut frameOut;
- Queue<byte[]> frameDatas = null;
- byte[] data = null;
- while (_isGrabbing)
- {
- if(FrameOuts.Count == 0) Thread.Sleep(5);
- bool BRet = FrameOuts.TryDequeue(out frameOut);
- if (BRet)
- {
- frameDatas = GetImageRowsData(frameOut);
- try
- {
- while (frameDatas!= null && frameDatas.Count > 0)
- {
- data = frameDatas.Dequeue();
- ImageBytes.Enqueue(data.Clone() as byte[]);
- if (ImageBytes.Count > 500)
- Console.WriteLine("ImageBytes.Count:" + ImageBytes.Count);
- data = null;
- }
- }
- catch (Exception e)
- {
- LOG.error("CameraClass_ImageRowsDataProcess " + e.Message);
- return;
- }
- device.StreamGrabber.FreeImageBuffer(frameOut);
- }
- }
- }
- /// <summary>
- /// 开启图像分割
- /// </summary>
- private void StartImageRowsDataFuntion()
- {
- try
- {
- // 开启线程
- if(_isGrabbing)
- {
- receiveThread = new Thread(ImageRowsDataProcess);
- receiveThread.Start();
- }
- }
- catch (Exception ex)
- {
- LOG.error("Start thread failed!, " + ex.Message);
- throw;
- }
- }
- /// <summary>
- /// 开启采集
- /// </summary>
- private void StartReceiveFuntion()
- {
- try
- {
- // 标志位置位true
- _isGrabbing = true;
- device.StreamGrabber.SetImageNodeNum(100);
- device.StreamGrabber.StartGrabbing();
- // 开启线程
- receiveThread = new Thread(ReceiveThreadProcess)
- {
- Priority = ThreadPriority.Highest
- };
- receiveThread.Start();
- }
- catch (Exception ex)
- {
- LOG.error("Start thread failed!, " + ex.Message);
- throw;
- }
- }
- /// <summary>
- /// 关闭采集线程
- /// </summary>
- private void StopReceiveAndImageRowsDataFuntion()
- {
- try
- {
- // 标志位设为false
- _isGrabbing = false;
- if (device == null) return;
- int ret = device.StreamGrabber.StopGrabbing();
- if (ret != MvError.MV_OK)
- {
- LOG.error(("Stop grabbing failed:{0:x8}", ret));
- return;
- }
- if (receiveThread != null&&receiveThread.IsAlive)
- receiveThread.Join();
- }
- catch (Exception ex)
- {
- LOG.error("Stop thread failed!, " + ex.Message);
- throw;
- }
- }
- /// <summary>
- /// 采集线程
- /// </summary>
- private void ReceiveThreadProcess()
- {
- while (_isGrabbing)
- {
- IFrameOut frameOut;
- int BRet = device.StreamGrabber.GetImageBuffer(100, out frameOut);
- if (BRet == MvError.MV_OK)
- {
- FrameOuts.Enqueue(frameOut.Clone() as IFrameOut);
- if (lastframeNum == -1)
- {
- lastframeNum = frameOut.FrameNum;
- }
- else if (lastframeNum == frameOut.FrameNum - 1)
- {
- lastframeNum = frameOut.FrameNum;
- }
- else
- {
- //丢帧记录
- LOG.log(string.Format("lost frame: Width[{0}] , Height[{1}] , FrameNum[{2}] ,Frevous[{3}]",
- frameOut.Image.Width, frameOut.Image.Height, frameOut.FrameNum - 1, lastframeNum), 5);
- Console.WriteLine("lost frame: Width[{0}] , Height[{1}] , FrameNum[{2}] ,Frevous[{3}]",
- frameOut.Image.Width, frameOut.Image.Height, frameOut.FrameNum - 1, lastframeNum);
- lastframeNum = frameOut.FrameNum;
- }
- device.StreamGrabber.FreeImageBuffer(frameOut);
- }
- }
- }
- /// <summary>
- /// 读取图像像素信息(单行)
- /// </summary>
- /// <param name="frameOut">帧数据</param>
- /// <returns></returns>
- 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;
- }
- /// <summary>
- /// 读取图像像素信息(多行)
- /// </summary>
- /// <param name="frameOut"></param>
- /// <returns></returns>
- private Queue<byte[]> GetImageRowsData(IFrameOut frameOut)
- {
- //创建
- Queue<byte[]> PixelDatas = new Queue<byte[]>();
- 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;
- }
- /// <summary>
- /// 帧获取回调事件
- /// </summary>
- /// <param name="sender"></param>
- /// <param name="e"></param>
- private void FrameGrabedEventHandler(object sender, FrameGrabbedEventArgs e)
- {
- if (e.FrameOut.Image.PixelData.Count() == 0)
- {
- LOG.log("FrameGrabedEventHandler: PixelData is null", 0);
- return;
- }
- if (!_isGrabbing) return;
- FrameOuts.Enqueue(e.FrameOut.Clone() as IFrameOut);
- if (lastframeNum == -1)
- {
- lastframeNum = e.FrameOut.FrameNum;
- }
- else if (lastframeNum == e.FrameOut.FrameNum - 1)
- {
- lastframeNum = e.FrameOut.FrameNum;
- }
- else
- {
- //丢帧记录
- LOG.log(string.Format("lost frame: Width[{0}] , Height[{1}] , FrameNum[{2}] ,Frevous[{3}]",
- e.FrameOut.Image.Width, e.FrameOut.Image.Height, e.FrameOut.FrameNum - 1, lastframeNum), 5);
- lastframeNum = e.FrameOut.FrameNum;
- }
- }
- /// <summary>
- /// 开启事件获取图像
- /// </summary>
- private void StartEventGetImage()
- {
- //ch: 设置合适的缓存节点数量 | en: Setting the appropriate number of image nodes
- device.StreamGrabber.SetImageNodeNum(50);
- // ch:注册回调函数 | en:Register image callback
- device.StreamGrabber.FrameGrabedEvent += FrameGrabedEventHandler;
- // ch:开启抓图 || en: start grab image
- int ret = device.StreamGrabber.StartGrabbing();
- if (ret != MvError.MV_OK)
- {
- LOG.error(string.Format("Start grabbing failed:{0}", ret));
- return;
- }
- Console.ReadLine();
- }
- /// <summary>
- /// 停止事件获取图像
- /// </summary>
- private void StopEventGetImage()
- {
- if (device == null) return;
- int ret = device.StreamGrabber.StopGrabbing();
- if (ret != MvError.MV_OK)
- {
- Console.WriteLine("Stop grabbing failed:{0:x8}", ret);
- return;
- }
- // ch:注册回调函数 | en:Register image callback
- device.StreamGrabber.FrameGrabedEvent -= FrameGrabedEventHandler;
- }
- #endregion
- }
- }
|