using DVPCameraType; using OpenCvSharp; using System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using System.Net.NetworkInformation; using System.Runtime.InteropServices; using System.Text; using System.Threading; using System.Threading.Tasks; using System.Xml.Linq; using static DVPCameraType.DVPCamera; using static System.Windows.Forms.VisualStyles.VisualStyleElement; public class MGSCameraDriver { private uint m_handle = 0; private dvpCameraInfo stDevInfo = new dvpCameraInfo(); private dvpStatus nRet = dvpStatus.DVP_STATUS_OK; private DVPCamera.dvpEventCallback pCallBackFunc; /// /// 相机拍照计数 /// public volatile int SnapshotCount = 0; /// /// 当前相机的配置 /// public bool IfSuccess = false; private float _lastExposure = 0; private float _lastGain = 0; #region CameraBase public bool IsValidHandle(uint handle) { bool bValidHandle = false; dvpStatus status = DVPCamera.dvpIsValid(handle, ref bValidHandle); if (status == dvpStatus.DVP_STATUS_OK) { return bValidHandle; } return false; } /// /// 获取曝光 /// /// public double dvpGetExposure() { dvpStatus status; double exposure = 0; float gain = 0; if (IsValidHandle(m_handle)) { // 读取曝光 status = DVPCamera.dvpGetExposure(m_handle, ref exposure); if (status == dvpStatus.DVP_STATUS_OK) { //opConfig.Exposure = (float)exposure; return exposure; } } return exposure; } /// /// 获取增益 /// /// public float dvpGetAnalogGain() { dvpStatus status; double exposure = 0; float gain = 0; if (IsValidHandle(m_handle)) { // 读取曝光 status = DVPCamera.dvpGetAnalogGain(m_handle, ref gain); if (status == dvpStatus.DVP_STATUS_OK) { //opConfig.Exposure = (float)exposure; return gain; } } return gain; } //public override IOperationConfig GetOperationConfigFromDevice() //{ // MGSCameraOperationConfig opConfig = new MGSCameraOperationConfig(); // dvpStatus status; // double exposure = 0; // float gain = 0; // if (IsValidHandle(m_handle)) // { // // 读取曝光 // status = DVPCamera.dvpGetExposure(m_handle, ref exposure); // if (status == dvpStatus.DVP_STATUS_OK) // { // opConfig.Exposure = (float)exposure; // } // // 读取增益 // status = DVPCamera.dvpGetAnalogGain(m_handle, ref gain); // if (status == dvpStatus.DVP_STATUS_OK) // { // opConfig.Gain = gain; // } // } // return opConfig; //} //public override void UploadOperationConfig(IOperationConfig config) //{ // if (CurrentState != DeviceState.DSOpen) // { // return; // } // if (!IsValidHandle(m_handle)) // { // return; // } // CameraOprerationConfigBase opConfig = config as CameraOprerationConfigBase; // if (opConfig.Exposure != 0 && opConfig.Exposure != _lastExposure) // { // SetExposure(opConfig.Exposure); // _lastExposure = opConfig.Exposure; // } // if (opConfig.Gain != 0 && opConfig.Gain != _lastGain) // { // SetGain(opConfig.Gain); // _lastGain = opConfig.Gain; // } //} public void Init() { DVPCamera.dvpGetCameraInfo(m_handle, ref stDevInfo); _bufferImgSet = new Mat(); pCallBackFunc = new DVPCamera.dvpEventCallback(cbExceptiondelegate); } protected void Pause() { } protected void Resume() { } public class CamConfig { public string CameraName = "Cam1"; public double DefaultExposure; public float Gain; public bool IsDirectHardwareTrigger = true; } public CamConfig IIConfig; public void Start(string DeviceName) { try { DVPCamera.dvpGetCameraInfo(m_handle, ref stDevInfo); _bufferImgSet = new Mat(); pCallBackFunc = new DVPCamera.dvpEventCallback(cbExceptiondelegate); nRet = DVPCamera.dvpOpenByUserId(DeviceName, dvpOpenMode.OPEN_NORMAL, ref m_handle); // ch:打开设备 | en:Open device if (dvpStatus.DVP_STATUS_OK != nRet) { throw new Exception($"Create device failed:{nRet:x8}"); } nRet = DVPCamera.dvpSetTargetFormat(m_handle, (dvpStreamFormat)dvpImageFormat.FORMAT_BGR24); if (dvpStatus.DVP_STATUS_OK != nRet) { throw new Exception($"Set image format failed:{nRet:x8}"); } // ch:注册异常回调函数 | en:Register Exception Callback nRet = DVPCamera.dvpRegisterEventCallback(m_handle, pCallBackFunc, dvpEvent.EVENT_DISCONNECTED, IntPtr.Zero); if (nRet != dvpStatus.DVP_STATUS_OK) { throw new Exception($"Register expection callback failed:{nRet}"); } GC.KeepAlive(pCallBackFunc); dvpStatus status; double exposure = 0; float gain = 0; if (IsValidHandle(m_handle)) { // 读取曝光 //status = DVPCamera.dvpGetExposure(m_handle, ref exposure); //if (status == dvpStatus.DVP_STATUS_OK) //{ // IIConfig.DefaultExposure = (float)exposure; //} //// 读取增益 //status = DVPCamera.dvpGetAnalogGain(m_handle, ref gain); //if (status == dvpStatus.DVP_STATUS_OK) //{ // IIConfig.Gain = gain; //} } // ch:设置采集连续模式 | en:Set Continues Aquisition Mode if (false)//IIConfig.IsContinueMode) { // ch:设置触发模式为off || en:set trigger mode as off nRet = DVPCamera.dvpSetTriggerState(m_handle, false); if (dvpStatus.DVP_STATUS_OK != nRet) { throw new Exception("Set TriggerMode failed!"); } } else { // ch:设置触发模式为on || en:set trigger mode as on nRet = DVPCamera.dvpSetTriggerState(m_handle, true); if (dvpStatus.DVP_STATUS_OK != nRet) { throw new Exception("Set TriggerMode failed!"); } // 硬触发 if (false)//IIConfig.IsHardwareTrigger) { // ch:触发源选择:1 - Line1; | en:Trigger source select:1 - Line1; nRet = DVPCamera.dvpSetTriggerSource(m_handle, dvpTriggerSource.TRIGGER_SOURCE_LINE1); if (dvpStatus.DVP_STATUS_OK != nRet) { throw new Exception("Set Line1 Trigger failed!"); } // ch:注册回调函数 | en:Register image callback ImageCallback = new DVPCamera.dvpStreamCallback(ImageCallbackFunc); nRet = DVPCamera.dvpRegisterStreamCallback(m_handle, ImageCallback, dvpStreamEvent.STREAM_EVENT_PROCESSED, IntPtr.Zero); if (dvpStatus.DVP_STATUS_OK != nRet) { throw new Exception("Register image callback failed!"); } } else // 软触发 { nRet = DVPCamera.dvpSetTriggerSource(m_handle, dvpTriggerSource.TRIGGER_SOURCE_SOFTWARE); if (dvpStatus.DVP_STATUS_OK != nRet) { throw new Exception("Set Software Trigger failed!"); } //_proc = _dvpStreamCallback; //nRet = DVPCamera.dvpRegisterStreamCallback(m_handle, _proc, dvpStreamEvent.STREAM_EVENT_PROCESSED, IntPtr.Zero); //if (dvpStatus.DVP_STATUS_OK != nRet) //{ // throw new Exception("Register image callback failed!"); //} // ch:注册回调函数 | en:Register image callback ImageCallback = new DVPCamera.dvpStreamCallback(ImageCallbackFunc); nRet = DVPCamera.dvpRegisterStreamCallback(m_handle, ImageCallback, dvpStreamEvent.STREAM_EVENT_PROCESSED, IntPtr.Zero); if (dvpStatus.DVP_STATUS_OK != nRet) { throw new Exception("Register image callback failed!"); } using (Process curProcess = Process.GetCurrentProcess()) using (ProcessModule curModule = curProcess.MainModule) { status = DVPCamera.dvpRegisterStreamCallback(m_handle, _proc, dvpStreamEvent.STREAM_EVENT_PROCESSED, IntPtr.Zero); //Debug.Assert(status == dvpStatus.DVP_STATUS_OK); } } m_dfDisplayCount = 0; if (IsValidHandle(m_handle)) { dvpStreamState state = new dvpStreamState(); // Implement a button to start and stop according to the current video's status. status = DVPCamera.dvpGetStreamState(m_handle, ref state); if (state == dvpStreamState.STATE_STARTED) { nRet = DVPCamera.dvpStop(m_handle); } else { nRet = DVPCamera.dvpStart(m_handle); } Debug.Assert(status == dvpStatus.DVP_STATUS_OK); nRet = DVPCamera.dvpSetTriggerSource(m_handle, dvpTriggerSource.TRIGGER_SOURCE_SOFTWARE); if (dvpStatus.DVP_STATUS_OK != nRet) { throw new Exception("Set Software Trigger failed!"); } else { IfSuccess = true; } } // ch:开启抓图 || en: start grab image //nRet = DVPCamera.dvpStart(m_handle); //if (dvpStatus.DVP_STATUS_OK != nRet) //{ // throw new Exception($"Start grabbing failed:{nRet:x8}"); //} // 曝光 //if (IIConfig.DefaultExposure != 0) //{ // SetExposure(IIConfig.DefaultExposure); //} //// 增益 //if (IIConfig.Gain >= 0) //{ // SetGain(IIConfig.Gain); //} // 设置 触发延迟 //if (IIConfig.TriggerDelay > 0) //{ // nRet = DVPCamera.dvpSetTriggerDelay(m_handle, IIConfig.TriggerDelay); // if (nRet != dvpStatus.DVP_STATUS_OK) // { // throw new Exception("Set TriggerDelay failed!"); // } //} // 信号消抖 //if (IIConfig.LineDebouncerTime > 0) //{ // nRet = DVPCamera.dvpSetTriggerJitterFilter(m_handle, IIConfig.LineDebouncerTime); // if (nRet != dvpStatus.DVP_STATUS_OK) // { // throw new Exception($"LineDebouncerTime set failed:{nRet}"); // } //} } } catch (Exception e) { } } public void Stop() { // ch:停止抓图 | en:Stop grab image // check camear dvpStreamState StreamState = new dvpStreamState(); nRet = DVPCamera.dvpGetStreamState(m_handle, ref StreamState); Debug.Assert(nRet == dvpStatus.DVP_STATUS_OK); if (StreamState == dvpStreamState.STATE_STARTED) { // stop camera nRet = DVPCamera.dvpStop(m_handle); Debug.Assert(nRet == dvpStatus.DVP_STATUS_OK); if (nRet != dvpStatus.DVP_STATUS_OK) { throw new Exception($"Stop grabbing failed{nRet:x8}"); } } nRet = DVPCamera.dvpUnregisterEventCallback(m_handle, pCallBackFunc, dvpEvent.EVENT_DISCONNECTED, IntPtr.Zero); if (nRet != dvpStatus.DVP_STATUS_OK) { throw new Exception($"Unregister expection callback failed:{nRet}"); } // ch:关闭设备 | en:Close device nRet = DVPCamera.dvpClose(m_handle); if (nRet != dvpStatus.DVP_STATUS_OK) { throw new Exception($"Close device failed{nRet:x8}"); } m_handle = 0; } #endregion #region MGSCamera private DVPCamera.dvpStreamCallback ImageCallback; private DVPCamera.dvpStreamCallback _proc; private dvpFrameBuffer _frame = new dvpFrameBuffer(); private readonly ManualResetEvent _snapHandle = new ManualResetEvent(false); private bool _snapFlag = false; private Mat _bufferImgSet = null; private readonly ManualResetEvent _bufferHandle = new ManualResetEvent(false); public Action OnHImageOutput { get; set; } public static bool m_bTriggerMode = false; // Display param public static Stopwatch m_Stopwatch = new Stopwatch(); public static Double m_dfDisplayCount = 0; public static dvpCameraInfo[] m_info = new dvpCameraInfo[16]; public static int m_CamCount = 0; /// /// 设置曝光值 /// /// 曝光值 /// private void SetExposure(double exposure) { // 使用自动曝光 if (false) { // 设置自动曝光 //nRet = DVPCamera.dvpSetAeOperation(m_handle, dvpAeOperation.AE_OP_CONTINUOUS); if (nRet != dvpStatus.DVP_STATUS_OK) { throw new Exception($"Exposure set failed:{nRet}"); } // 设置曝光值 nRet = DVPCamera.dvpSetAeTarget(m_handle, (int)exposure); if (nRet != dvpStatus.DVP_STATUS_OK) { throw new Exception($"Exposure set failed:{nRet}"); } } else // 不适用自动曝光 { // 关闭自动曝光 nRet = DVPCamera.dvpSetAeOperation(m_handle, dvpAeOperation.AE_OP_OFF); if (nRet != dvpStatus.DVP_STATUS_OK) { throw new Exception($"Exposure set failed:{nRet}"); } // 设置曝光值 nRet = DVPCamera.dvpSetExposure(m_handle, exposure); if (nRet != dvpStatus.DVP_STATUS_OK) { throw new Exception($"Exposure set failed:{nRet}"); } } } /// /// 设置增益 /// /// /// private void SetGain(float gain) { // 设置增益 nRet = DVPCamera.dvpSetAnalogGain(m_handle, gain); if (nRet != dvpStatus.DVP_STATUS_OK) { throw new Exception($"Gain set failed:{nRet}"); } } public int ImageCallbackFunc(uint handle, dvpStreamEvent _event, IntPtr pContext, ref dvpFrame refFrame, IntPtr pBuffer) { try { if (true)//硬触发 { int nWidth = refFrame.iWidth; int nHeight = refFrame.iHeight; MatType matType = MatType.CV_8UC1; if (refFrame.format == dvpImageFormat.FORMAT_RGB24) { IntPtr pTemp = pBuffer; } else if (refFrame.format == dvpImageFormat.FORMAT_BGR24) { IntPtr pTemp = pBuffer; matType = MatType.CV_8UC3; } Mat _mat = new Mat(nHeight, nWidth, matType, pBuffer); //加入内部队列 //if (IIConfig.IsDirectHardwareTrigger) //{ // 传感器直接触发 收到图片后 传出 OnHImageOutput?.Invoke(DateTime.Now, _mat); // } //else //{ // _bufferImgSet = _mat; // // _bufferImgSetQueue.Enqueue(outImgSet); // _bufferHandle.Set(); //} //处理完图片 会清理内部队列的图像 //DisplayAndSaveOriginImage(imgSet.Id); } else if (_snapFlag) { _snapFlag = false; _frame = new dvpFrameBuffer { frame = refFrame, pData = pBuffer, }; _snapHandle.Set(); } } catch (Exception ex) { return dvpStatus.DVP_STATUS_GRAB_FAILED.ToInt(); } return dvpStatus.DVP_STATUS_OK.ToInt(); } private object _bufferLock = new object(); public void Snapshot() { try { Stopwatch sw = new Stopwatch(); sw.Start(); // ImageSet set = new ImageSet(); dvpFrameBuffer frameInfo = new dvpFrameBuffer(); nRet = dvpStatus.DVP_STATUS_OK; if (true)//如果不是持续模式 { // ch: 触发命令 || en: Trigger command nRet = DVPCamera.dvpTriggerFire(m_handle); if (dvpStatus.DVP_STATUS_OK != nRet) { throw new Exception($"相机拍照触发失败:{nRet}"); } } else { _snapHandle.Reset(); _snapFlag = true; _snapHandle.WaitOne(); //lock (_imgCallBackLock) { frameInfo.frame = _frame.frame; frameInfo.pData = _frame.pData; } } // ch:获取一帧图像 | en:Get one image if (dvpStatus.DVP_STATUS_OK == nRet) { Interlocked.Increment(ref SnapshotCount); if (frameInfo.pData != IntPtr.Zero) { if (nRet == dvpStatus.DVP_STATUS_OK) { dvpFrame pFrameInfo = frameInfo.frame; MatType matType = MatType.CV_8UC1; if (pFrameInfo.format == dvpImageFormat.FORMAT_RGB24) { } else if (pFrameInfo.format == dvpImageFormat.FORMAT_BGR24) { matType = MatType.CV_8UC3; } //HImage hImage = new HImage(); //hImage.GenImage1("byte", pFrameInfo.iWidth, pFrameInfo.iHeight, frameInfo.pData); Mat _mat = new Mat(pFrameInfo.iHeight, pFrameInfo.iWidth, matType, frameInfo.pData); OnHImageOutput?.Invoke(DateTime.Now, _mat); //_mat.ImWrite("D://123.jpg"); } } } else { throw new Exception($"Grap Image Failed:{nRet:x8}"); } sw.Stop(); // LogAsync(DateTime.Now, LogLevel.Information, $"取像耗时:{sw.ElapsedMilliseconds} ms"); } catch (Exception ex) { } } /// /// 回调函数 /// /// /// /// /// /// /// public int cbExceptiondelegate(uint handle, dvpEvent _event, IntPtr pContext, int param, ref dvpVariant refVariant) { if (_event == dvpEvent.EVENT_DISCONNECTED) { int reTryTimes = 3; do { try { Task.Delay(1000).Wait(); Stop(); //Start(); reTryTimes = -1; } catch (Exception ex) { reTryTimes--; if (reTryTimes > 0) { // LogAsync(DateTime.Now, LogLevel.Information, $"{Name}重新连接异常,{ex.GetExceptionMessage()}"); } else { throw ex; } } } while (reTryTimes > 0); } return dvpStatus.DVP_STATUS_OK.ToInt(); } #endregion }