| ¶Ô±ÈÐÂÎļþ |
| | |
| | | using MVSDK_Net; |
| | | using System; |
| | | using System.Collections.Generic; |
| | | using System.Diagnostics; |
| | | using System.Drawing.Imaging; |
| | | using System.Linq; |
| | | using System.Runtime.InteropServices; |
| | | using System.Text; |
| | | using System.Threading.Tasks; |
| | | |
| | | namespace LB_VisionProcesses.Cameras.HRCameras |
| | | { |
| | | /// <summary> |
| | | /// åç¿2Då·¥ä¸ç¸æºå®ç°ç±» |
| | | /// åºäºMVSDK_Net SDKå°è£
|
| | | /// </summary> |
| | | public class HRCamera : BaseCamera |
| | | { |
| | | #region ç§æåæ®µ |
| | | |
| | | private MyCamera _camera; // åç¿ç¸æºè®¾å¤å¯¹è±¡ |
| | | private Thread _grabThread; // å¾åééçº¿ç¨ |
| | | private bool _isGrabbing; // ééç¶ææ å¿ |
| | | private bool _threadRunning; // 线ç¨è¿è¡æ å¿ |
| | | private bool _handleCreated = false; // 奿æ¯å¦å·²å建 |
| | | private Thread _callbackThread; // åè°å¤ççº¿ç¨ |
| | | private List<IMVDefine.IMV_Frame> _frameList; // å¾åç¼åå表 |
| | | private readonly object _frameLock = new object(); // 帧ç¼åé |
| | | |
| | | // CopyMemory API声æ |
| | | [System.Runtime.InteropServices.DllImport("kernel32.dll", EntryPoint = "RtlMoveMemory")] |
| | | private static extern void CopyMemory(IntPtr dest, IntPtr src, uint count); |
| | | |
| | | #endregion |
| | | |
| | | #region æé 彿°åææå½æ° |
| | | |
| | | /// <summary> |
| | | /// æé 彿° |
| | | /// </summary> |
| | | public HRCamera() |
| | | { |
| | | _camera = new MyCamera(); |
| | | _frameList = new List<IMVDefine.IMV_Frame>(); |
| | | Brand = CameraBrand.HRCamera; |
| | | _isGrabbing = false; |
| | | _threadRunning = false; |
| | | } |
| | | |
| | | /// <summary> |
| | | /// ææå½æ° |
| | | /// </summary> |
| | | ~HRCamera() |
| | | { |
| | | Dispose(false); |
| | | } |
| | | |
| | | #endregion |
| | | |
| | | #region 设å¤ç®¡çæä½ |
| | | |
| | | /// <summary> |
| | | /// è·åç¸æºSNæä¸¾å表 |
| | | /// </summary> |
| | | /// <returns>ç¸æºSNå表</returns> |
| | | public override List<string> GetListEnum() |
| | | { |
| | | List<string> cameraList = new List<string>(); |
| | | |
| | | try |
| | | { |
| | | // æä¸¾ææè®¾å¤ |
| | | IMVDefine.IMV_DeviceList deviceList = new IMVDefine.IMV_DeviceList(); |
| | | IMVDefine.IMV_EInterfaceType interfaceType = IMVDefine.IMV_EInterfaceType.interfaceTypeAll; |
| | | |
| | | int result = MyCamera.IMV_EnumDevices(ref deviceList, (uint)interfaceType); |
| | | |
| | | if (result == IMVDefine.IMV_OK && deviceList.nDevNum > 0) |
| | | { |
| | | for (int i = 0; i < deviceList.nDevNum; i++) |
| | | { |
| | | IMVDefine.IMV_DeviceInfo deviceInfo = (IMVDefine.IMV_DeviceInfo) |
| | | Marshal.PtrToStructure( |
| | | deviceList.pDevInfo + Marshal.SizeOf(typeof(IMVDefine.IMV_DeviceInfo)) * i, |
| | | typeof(IMVDefine.IMV_DeviceInfo)); |
| | | |
| | | string cameraInfo = $"{deviceInfo.cameraName}[{deviceInfo.serialNumber}]"; |
| | | cameraList.Add(cameraInfo); |
| | | } |
| | | } |
| | | else |
| | | { |
| | | // è®°å½æ¥å¿ææåºå¼å¸¸ |
| | | //throw new Exception($"æä¸¾è®¾å¤å¤±è´¥ï¼é误ç ï¼{result}"); |
| | | Debug.WriteLine("æä¸¾è®¾å¤å¤±è´¥ï¼"); |
| | | } |
| | | } |
| | | catch (Exception ex) |
| | | { |
| | | // è®°å½é误æ¥å¿ |
| | | System.Diagnostics.Debug.WriteLine($"è·åç¸æºå表失败ï¼{ex.Message}"); |
| | | throw; |
| | | } |
| | | |
| | | return cameraList; |
| | | } |
| | | |
| | | /// <summary> |
| | | /// åå§åç¸æºè®¾å¤ |
| | | /// </summary> |
| | | /// <param name="SN">ç¸æºåºåå·</param> |
| | | /// <param name="Handle">çªå£å¥æï¼å¯éï¼</param> |
| | | /// <returns>åå§åæ¯å¦æå</returns> |
| | | public override bool InitDevice(string SN, object Handle = null) |
| | | { |
| | | try |
| | | { |
| | | // ç¡®ä¿å½»åºå
³é忏
ç |
| | | if (_camera != null) |
| | | { |
| | | if (_camera.IMV_IsOpen()) |
| | | { |
| | | _camera.IMV_Close(); |
| | | } |
| | | |
| | | if (_handleCreated) |
| | | { |
| | | _camera.IMV_DestroyHandle(); |
| | | _handleCreated = false; |
| | | } |
| | | } |
| | | |
| | | // æä¸¾è®¾å¤å¹¶å¹é
SN |
| | | List<string> cameraList = GetListEnum(); |
| | | int cameraIndex = -1; |
| | | |
| | | for (int i = 0; i < cameraList.Count; i++) |
| | | { |
| | | if (cameraList[i].Contains(SN)) |
| | | { |
| | | cameraIndex = i; |
| | | break; |
| | | } |
| | | } |
| | | |
| | | if (cameraIndex == -1) |
| | | { |
| | | throw new Exception($"æªæ¾å°åºåå·ä¸º {SN} çç¸æº"); |
| | | } |
| | | |
| | | // å建设å¤å¥æ |
| | | int result = _camera.IMV_CreateHandle(IMVDefine.IMV_ECreateHandleMode.modeByIndex, cameraIndex); |
| | | if (result != IMVDefine.IMV_OK) |
| | | { |
| | | throw new Exception($"å建设å¤å¥æå¤±è´¥ï¼é误ç ï¼{result}"); |
| | | } |
| | | _handleCreated = true; |
| | | |
| | | // æå¼è®¾å¤ |
| | | result = _camera.IMV_Open(); |
| | | if (result != IMVDefine.IMV_OK) |
| | | { |
| | | throw new Exception($"æå¼ç¸æºå¤±è´¥ï¼é误ç ï¼{result}"); |
| | | } |
| | | |
| | | // 设置设å¤å±æ§ |
| | | this.SN = SN; |
| | | isGrabbing = false; |
| | | |
| | | // 设置ç¼å个æ°ä¸º8 |
| | | _camera.IMV_SetBufferCount(8); |
| | | |
| | | return true; |
| | | } |
| | | catch (Exception ex) |
| | | { |
| | | System.Diagnostics.Debug.WriteLine($"åå§åç¸æºå¤±è´¥ï¼{ex.Message}"); |
| | | return false; |
| | | } |
| | | } |
| | | |
| | | /// <summary> |
| | | /// å
³éç¸æºè®¾å¤ |
| | | /// </summary> |
| | | /// <returns>å
³éæ¯å¦æå</returns> |
| | | public override bool CloseDevice() |
| | | { |
| | | try |
| | | { |
| | | if (_camera == null) |
| | | return true; |
| | | |
| | | // 忢éé |
| | | if (_camera.IMV_IsGrabbing()) |
| | | { |
| | | StopGrabbing(); |
| | | } |
| | | |
| | | // å
³éè®¾å¤ |
| | | if (_camera.IMV_IsOpen()) |
| | | { |
| | | int result = _camera.IMV_Close(); |
| | | if (result != IMVDefine.IMV_OK) |
| | | { |
| | | System.Diagnostics.Debug.WriteLine($"å
³éç¸æºå¤±è´¥ï¼é误ç ï¼{result}"); |
| | | } |
| | | } |
| | | |
| | | // 鿝奿 |
| | | if (_handleCreated) |
| | | { |
| | | _camera.IMV_DestroyHandle(); |
| | | _handleCreated = false; |
| | | } |
| | | |
| | | // éæ¾èµæº |
| | | _isGrabbing = false; |
| | | isGrabbing = false; |
| | | |
| | | // æ¸
ç帧ç¼å |
| | | lock (_frameLock) |
| | | { |
| | | foreach (var frame in _frameList) |
| | | { |
| | | var tempFrame = frame; // å建临æ¶åé |
| | | _camera.IMV_ReleaseFrame(ref tempFrame); |
| | | } |
| | | _frameList.Clear(); |
| | | } |
| | | |
| | | return true; |
| | | } |
| | | catch (Exception ex) |
| | | { |
| | | System.Diagnostics.Debug.WriteLine($"å
³éç¸æºå¤±è´¥ï¼{ex.Message}"); |
| | | return false; |
| | | } |
| | | } |
| | | |
| | | #endregion |
| | | |
| | | #region å¾åééæä½ |
| | | |
| | | /// <summary> |
| | | /// å¼å§å¾åéé |
| | | /// </summary> |
| | | /// <returns>ééå¯å¨æ¯å¦æå</returns> |
| | | public override bool StartGrabbing() |
| | | { |
| | | try |
| | | { |
| | | if (_camera == null || !_camera.IMV_IsOpen()) |
| | | { |
| | | throw new Exception("ç¸æºæªæå¼"); |
| | | } |
| | | |
| | | // åæ¢ç°æéé |
| | | if (_isGrabbing) |
| | | { |
| | | StopGrabbing(); |
| | | } |
| | | |
| | | // å¯å¨éé |
| | | int result = _camera.IMV_StartGrabbing(); |
| | | if (result != IMVDefine.IMV_OK) |
| | | { |
| | | throw new Exception($"å¯å¨éé失败ï¼é误ç ï¼{result}"); |
| | | } |
| | | |
| | | _isGrabbing = true; |
| | | isGrabbing = true; |
| | | |
| | | // å¯å¨ééçº¿ç¨ |
| | | _threadRunning = true; |
| | | _grabThread = new Thread(GrabThreadProc); |
| | | _grabThread.IsBackground = true; |
| | | _grabThread.Start(); |
| | | |
| | | return true; |
| | | } |
| | | catch (Exception ex) |
| | | { |
| | | System.Diagnostics.Debug.WriteLine($"å¯å¨éé失败ï¼{ex.Message}"); |
| | | _isGrabbing = false; |
| | | isGrabbing = false; |
| | | return false; |
| | | } |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 忢å¾åéé |
| | | /// </summary> |
| | | /// <returns>忢æ¯å¦æå</returns> |
| | | public override bool StopGrabbing() |
| | | { |
| | | try |
| | | { |
| | | if (_camera == null || !_isGrabbing) |
| | | return true; |
| | | |
| | | // åæ¢çº¿ç¨ |
| | | _threadRunning = false; |
| | | if (_grabThread != null && _grabThread.IsAlive) |
| | | { |
| | | _grabThread.Join(1000); |
| | | _grabThread = null; |
| | | } |
| | | |
| | | // 忢éé |
| | | int result = _camera.IMV_StopGrabbing(); |
| | | if (result != IMVDefine.IMV_OK) |
| | | { |
| | | System.Diagnostics.Debug.WriteLine($"忢éé失败ï¼é误ç ï¼{result}"); |
| | | } |
| | | |
| | | _isGrabbing = false; |
| | | isGrabbing = false; |
| | | |
| | | // æ¸
çç¼å |
| | | lock (_frameLock) |
| | | { |
| | | foreach (var frame in _frameList) |
| | | { |
| | | var tempFrame = frame; // å建临æ¶åé |
| | | _camera.IMV_ReleaseFrame(ref tempFrame); |
| | | } |
| | | _frameList.Clear(); |
| | | } |
| | | |
| | | return true; |
| | | } |
| | | catch (Exception ex) |
| | | { |
| | | System.Diagnostics.Debug.WriteLine($"忢éé失败ï¼{ex.Message}"); |
| | | return false; |
| | | } |
| | | } |
| | | |
| | | /// <summary> |
| | | /// æ§è¡è½¯è§¦å |
| | | /// </summary> |
| | | /// <returns>è§¦åæ¯å¦æå</returns> |
| | | public override bool SoftTrigger() |
| | | { |
| | | try |
| | | { |
| | | if (_camera == null || !_camera.IMV_IsOpen()) |
| | | { |
| | | throw new Exception("ç¸æºæªæå¼"); |
| | | } |
| | | |
| | | int result = _camera.IMV_ExecuteCommandFeature("TriggerSoftware"); |
| | | return result == IMVDefine.IMV_OK; |
| | | } |
| | | catch (Exception ex) |
| | | { |
| | | System.Diagnostics.Debug.WriteLine($"软触å失败ï¼{ex.Message}"); |
| | | return false; |
| | | } |
| | | } |
| | | |
| | | #endregion |
| | | |
| | | #region åæ°è®¾ç½®åè·å |
| | | |
| | | /// <summary> |
| | | /// è®¾ç½®è§¦åæ¨¡å¼ |
| | | /// </summary> |
| | | /// <param name="mode">è§¦åæ¨¡å¼</param> |
| | | /// <param name="source">è§¦åæº</param> |
| | | /// <returns>设置æ¯å¦æå</returns> |
| | | public override bool SetTriggerMode(TriggerMode mode, TriggerSource source = TriggerSource.Line0) |
| | | { |
| | | try |
| | | { |
| | | if (_camera == null || !_camera.IMV_IsOpen()) |
| | | { |
| | | throw new Exception("ç¸æºæªæå¼"); |
| | | } |
| | | |
| | | // è®¾ç½®è§¦åæ¨¡å¼ |
| | | string triggerMode = mode == TriggerMode.On ? "On" : "Off"; |
| | | int result = _camera.IMV_SetEnumFeatureSymbol("TriggerMode", triggerMode); |
| | | if (result != IMVDefine.IMV_OK) |
| | | { |
| | | throw new Exception($"è®¾ç½®è§¦åæ¨¡å¼å¤±è´¥ï¼é误ç ï¼{result}"); |
| | | } |
| | | |
| | | // è®¾ç½®è§¦åæº |
| | | if (mode == TriggerMode.On) |
| | | { |
| | | string triggerSource = GetTriggerSourceString(source); |
| | | result = _camera.IMV_SetEnumFeatureSymbol("TriggerSource", triggerSource); |
| | | if (result != IMVDefine.IMV_OK) |
| | | { |
| | | throw new Exception($"è®¾ç½®è§¦åæºå¤±è´¥ï¼é误ç ï¼{result}"); |
| | | } |
| | | } |
| | | |
| | | return true; |
| | | } |
| | | catch (Exception ex) |
| | | { |
| | | System.Diagnostics.Debug.WriteLine($"è®¾ç½®è§¦åæ¨¡å¼å¤±è´¥ï¼{ex.Message}"); |
| | | return false; |
| | | } |
| | | } |
| | | |
| | | /// <summary> |
| | | /// è·åè§¦åæ¨¡å¼ |
| | | /// </summary> |
| | | /// <param name="mode">è§¦åæ¨¡å¼</param> |
| | | /// <param name="source">è§¦åæº</param> |
| | | /// <returns>è·åæ¯å¦æå</returns> |
| | | public override bool GetTriggerMode(out TriggerMode mode, out TriggerSource source) |
| | | { |
| | | mode = TriggerMode.Off; |
| | | source = TriggerSource.Software; |
| | | |
| | | try |
| | | { |
| | | if (_camera == null || !_camera.IMV_IsOpen()) |
| | | { |
| | | throw new Exception("ç¸æºæªæå¼"); |
| | | } |
| | | |
| | | // è·åè§¦åæ¨¡å¼ |
| | | IMVDefine.IMV_String triggerMode = new IMVDefine.IMV_String(); |
| | | int result = _camera.IMV_GetEnumFeatureSymbol("TriggerMode", ref triggerMode); |
| | | if (result == IMVDefine.IMV_OK) |
| | | { |
| | | mode = triggerMode.str == "On" ? TriggerMode.On : TriggerMode.Off; |
| | | } |
| | | |
| | | // è·åè§¦åæº |
| | | IMVDefine.IMV_String triggerSource = new IMVDefine.IMV_String(); |
| | | result = _camera.IMV_GetEnumFeatureSymbol("TriggerSource", ref triggerSource); |
| | | if (result == IMVDefine.IMV_OK) |
| | | { |
| | | source = GetTriggerSourceFromString(triggerSource.str); |
| | | } |
| | | |
| | | return true; |
| | | } |
| | | catch (Exception ex) |
| | | { |
| | | System.Diagnostics.Debug.WriteLine($"è·åè§¦åæ¨¡å¼å¤±è´¥ï¼{ex.Message}"); |
| | | return false; |
| | | } |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 设置æå
æ¶é´ |
| | | /// </summary> |
| | | /// <param name="value">æå
æ¶é´ï¼å¾®ç§ï¼</param> |
| | | /// <returns>设置æ¯å¦æå</returns> |
| | | public override bool SetExpouseTime(double value) |
| | | { |
| | | try |
| | | { |
| | | if (_camera == null || !_camera.IMV_IsOpen()) |
| | | { |
| | | throw new Exception("ç¸æºæªæå¼"); |
| | | } |
| | | |
| | | // éªè¯æå
æ¶é´èå´ |
| | | double minExp = 0, maxExp = 0; |
| | | int result = _camera.IMV_GetDoubleFeatureMin("ExposureTime", ref minExp); |
| | | if (result != IMVDefine.IMV_OK) |
| | | { |
| | | throw new Exception($"è·åæå
æ¶é´æå°å¼å¤±è´¥ï¼é误ç ï¼{result}"); |
| | | } |
| | | |
| | | result = _camera.IMV_GetDoubleFeatureMax("ExposureTime", ref maxExp); |
| | | if (result != IMVDefine.IMV_OK) |
| | | { |
| | | throw new Exception($"è·åæå
æ¶é´æå¤§å¼å¤±è´¥ï¼é误ç ï¼{result}"); |
| | | } |
| | | |
| | | if (value < minExp || value > maxExp) |
| | | { |
| | | throw new Exception($"æå
æ¶é´è¶
åºèå´ï¼ææèå´ï¼{minExp} - {maxExp}"); |
| | | } |
| | | |
| | | // 设置æå
æ¶é´ |
| | | result = _camera.IMV_SetDoubleFeatureValue("ExposureTime", value); |
| | | if (result != IMVDefine.IMV_OK) |
| | | { |
| | | throw new Exception($"设置æå
æ¶é´å¤±è´¥ï¼é误ç ï¼{result}"); |
| | | } |
| | | |
| | | return true; |
| | | } |
| | | catch (Exception ex) |
| | | { |
| | | System.Diagnostics.Debug.WriteLine($"设置æå
æ¶é´å¤±è´¥ï¼{ex.Message}"); |
| | | return false; |
| | | } |
| | | } |
| | | |
| | | /// <summary> |
| | | /// è·åæå
æ¶é´ |
| | | /// </summary> |
| | | /// <param name="value">æå
æ¶é´</param> |
| | | /// <returns>è·åæ¯å¦æå</returns> |
| | | public override bool GetExpouseTime(out double value) |
| | | { |
| | | value = 0; |
| | | |
| | | try |
| | | { |
| | | if (_camera == null || !_camera.IMV_IsOpen()) |
| | | { |
| | | throw new Exception("ç¸æºæªæå¼"); |
| | | } |
| | | |
| | | int result = _camera.IMV_GetDoubleFeatureValue("ExposureTime", ref value); |
| | | return result == IMVDefine.IMV_OK; |
| | | } |
| | | catch (Exception ex) |
| | | { |
| | | System.Diagnostics.Debug.WriteLine($"è·åæå
æ¶é´å¤±è´¥ï¼{ex.Message}"); |
| | | return false; |
| | | } |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 设置å¢ç |
| | | /// </summary> |
| | | /// <param name="gain">å¢çå¼</param> |
| | | /// <returns>设置æ¯å¦æå</returns> |
| | | public override bool SetGain(double gain) |
| | | { |
| | | try |
| | | { |
| | | if (_camera == null || !_camera.IMV_IsOpen()) |
| | | { |
| | | throw new Exception("ç¸æºæªæå¼"); |
| | | } |
| | | |
| | | string gainFeature = _camera.IMV_FeatureIsValid("Gain") ? "Gain" : "GainRaw"; |
| | | |
| | | // éªè¯å¢çèå´ |
| | | double minGain = 0, maxGain = 0; |
| | | int result = _camera.IMV_GetDoubleFeatureMin(gainFeature, ref minGain); |
| | | if (result != IMVDefine.IMV_OK) |
| | | { |
| | | throw new Exception($"è·åå¢çæå°å¼å¤±è´¥ï¼é误ç ï¼{result}"); |
| | | } |
| | | |
| | | result = _camera.IMV_GetDoubleFeatureMax(gainFeature, ref maxGain); |
| | | if (result != IMVDefine.IMV_OK) |
| | | { |
| | | throw new Exception($"è·åå¢çæå¤§å¼å¤±è´¥ï¼é误ç ï¼{result}"); |
| | | } |
| | | |
| | | if (gain < minGain) gain = minGain; |
| | | if (gain > maxGain) gain = maxGain; |
| | | |
| | | // 设置å¢ç |
| | | result = _camera.IMV_SetDoubleFeatureValue(gainFeature, gain); |
| | | if (result != IMVDefine.IMV_OK) |
| | | { |
| | | throw new Exception($"设置å¢ç失败ï¼é误ç ï¼{result}"); |
| | | } |
| | | |
| | | return true; |
| | | } |
| | | catch (Exception ex) |
| | | { |
| | | System.Diagnostics.Debug.WriteLine($"设置å¢ç失败ï¼{ex.Message}"); |
| | | return false; |
| | | } |
| | | } |
| | | |
| | | /// <summary> |
| | | /// è·åå¢çå¼ |
| | | /// </summary> |
| | | /// <param name="gain">å¢çå¼</param> |
| | | /// <returns>è·åæ¯å¦æå</returns> |
| | | public override bool GetGain(out double gain) |
| | | { |
| | | gain = 0; |
| | | |
| | | try |
| | | { |
| | | if (_camera == null || !_camera.IMV_IsOpen()) |
| | | { |
| | | throw new Exception("ç¸æºæªæå¼"); |
| | | } |
| | | |
| | | string gainFeature = _camera.IMV_FeatureIsValid("Gain") ? "Gain" : "GainRaw"; |
| | | int result = _camera.IMV_GetDoubleFeatureValue(gainFeature, ref gain); |
| | | return result == IMVDefine.IMV_OK; |
| | | } |
| | | catch (Exception ex) |
| | | { |
| | | System.Diagnostics.Debug.WriteLine($"è·åå¢ç失败ï¼{ex.Message}"); |
| | | return false; |
| | | } |
| | | } |
| | | |
| | | /// <summary> |
| | | /// è®¾ç½®è§¦åææ§ |
| | | /// </summary> |
| | | /// <param name="polarity">è§¦åææ§</param> |
| | | /// <returns>æ¯å¦æå</returns> |
| | | public override bool SetTriggerPolarity(TriggerPolarity polarity) |
| | | { |
| | | try |
| | | { |
| | | if (_camera == null || !_camera.IMV_IsOpen()) return false; |
| | | |
| | | string activation = (polarity == TriggerPolarity.RisingEdge || polarity == TriggerPolarity.HighLevel) |
| | | ? "RisingEdge" : "FallingEdge"; |
| | | |
| | | int result = _camera.IMV_SetEnumFeatureSymbol("TriggerActivation", activation); |
| | | return result == IMVDefine.IMV_OK; |
| | | } |
| | | catch (Exception ex) |
| | | { |
| | | System.Diagnostics.Debug.WriteLine($"è®¾ç½®è§¦åææ§å¤±è´¥ï¼{ex.Message}"); |
| | | return false; |
| | | } |
| | | } |
| | | |
| | | /// <summary> |
| | | /// è·åè§¦åææ§ |
| | | /// </summary> |
| | | /// <param name="polarity">è§¦åææ§</param> |
| | | /// <returns>æ¯å¦æå</returns> |
| | | public override bool GetTriggerPolarity(out TriggerPolarity polarity) |
| | | { |
| | | polarity = TriggerPolarity.RisingEdge; |
| | | try |
| | | { |
| | | if (_camera == null || !_camera.IMV_IsOpen()) return false; |
| | | |
| | | IMVDefine.IMV_String activation = new IMVDefine.IMV_String(); |
| | | int result = _camera.IMV_GetEnumFeatureSymbol("TriggerActivation", ref activation); |
| | | if (result == IMVDefine.IMV_OK) |
| | | { |
| | | polarity = activation.str == "RisingEdge" ? TriggerPolarity.RisingEdge : TriggerPolarity.FallingEdge; |
| | | return true; |
| | | } |
| | | return false; |
| | | } |
| | | catch (Exception ex) |
| | | { |
| | | System.Diagnostics.Debug.WriteLine($"è·åè§¦åææ§å¤±è´¥ï¼{ex.Message}"); |
| | | return false; |
| | | } |
| | | } |
| | | |
| | | /// <summary> |
| | | /// è®¾ç½®è§¦åæ»¤æ³¢æ¶é´ (us) |
| | | /// </summary> |
| | | public override bool SetTriggerFliter(double flitertime) |
| | | { |
| | | try |
| | | { |
| | | if (_camera == null || !_camera.IMV_IsOpen()) return false; |
| | | |
| | | // åç¿ç¸æºéå¸¸ä½¿ç¨ LineDebouncerTime æ§å¶æ»¤æ³¢ |
| | | if (_camera.IMV_FeatureIsValid("LineDebouncerTime")) |
| | | { |
| | | int result = _camera.IMV_SetDoubleFeatureValue("LineDebouncerTime", flitertime); |
| | | return result == IMVDefine.IMV_OK; |
| | | } |
| | | return false; |
| | | } |
| | | catch (Exception ex) |
| | | { |
| | | System.Diagnostics.Debug.WriteLine($"è®¾ç½®è§¦åæ»¤æ³¢å¤±è´¥ï¼{ex.Message}"); |
| | | return false; |
| | | } |
| | | } |
| | | |
| | | /// <summary> |
| | | /// è·åè§¦åæ»¤æ³¢æ¶é´ (us) |
| | | /// </summary> |
| | | public override bool GetTriggerFliter(out double flitertime) |
| | | { |
| | | flitertime = 0; |
| | | try |
| | | { |
| | | if (_camera == null || !_camera.IMV_IsOpen()) return false; |
| | | |
| | | if (_camera.IMV_FeatureIsValid("LineDebouncerTime")) |
| | | { |
| | | int result = _camera.IMV_GetDoubleFeatureValue("LineDebouncerTime", ref flitertime); |
| | | return result == IMVDefine.IMV_OK; |
| | | } |
| | | return false; |
| | | } |
| | | catch (Exception ex) |
| | | { |
| | | System.Diagnostics.Debug.WriteLine($"è·åè§¦åæ»¤æ³¢å¤±è´¥ï¼{ex.Message}"); |
| | | return false; |
| | | } |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 设置触åå»¶æ¶ (us) |
| | | /// </summary> |
| | | public override bool SetTriggerDelay(double delay) |
| | | { |
| | | try |
| | | { |
| | | if (_camera == null || !_camera.IMV_IsOpen()) return false; |
| | | |
| | | if (_camera.IMV_FeatureIsValid("TriggerDelay")) |
| | | { |
| | | int result = _camera.IMV_SetDoubleFeatureValue("TriggerDelay", delay); |
| | | return result == IMVDefine.IMV_OK; |
| | | } |
| | | return false; |
| | | } |
| | | catch (Exception ex) |
| | | { |
| | | System.Diagnostics.Debug.WriteLine($"设置触åå»¶æ¶å¤±è´¥ï¼{ex.Message}"); |
| | | return false; |
| | | } |
| | | } |
| | | |
| | | /// <summary> |
| | | /// è·å触åå»¶æ¶ (us) |
| | | /// </summary> |
| | | public override bool GetTriggerDelay(out double delay) |
| | | { |
| | | delay = 0; |
| | | try |
| | | { |
| | | if (_camera == null || !_camera.IMV_IsOpen()) return false; |
| | | |
| | | if (_camera.IMV_FeatureIsValid("TriggerDelay")) |
| | | { |
| | | int result = _camera.IMV_GetDoubleFeatureValue("TriggerDelay", ref delay); |
| | | return result == IMVDefine.IMV_OK; |
| | | } |
| | | return false; |
| | | } |
| | | catch (Exception ex) |
| | | { |
| | | System.Diagnostics.Debug.WriteLine($"è·å触åå»¶æ¶å¤±è´¥ï¼{ex.Message}"); |
| | | return false; |
| | | } |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 设置信å·çº¿æ¨¡å¼ |
| | | /// </summary> |
| | | public override bool SetLineMode(IOLines line, LineMode mode) |
| | | { |
| | | try |
| | | { |
| | | if (_camera == null || !_camera.IMV_IsOpen()) return false; |
| | | |
| | | // éæ©çº¿è·¯ |
| | | int result = _camera.IMV_SetEnumFeatureSymbol("LineSelector", line.ToString()); |
| | | if (result != IMVDefine.IMV_OK) return false; |
| | | |
| | | // è®¾ç½®æ¨¡å¼ |
| | | string lineMode = mode == LineMode.Input ? "Input" : "Output"; |
| | | result = _camera.IMV_SetEnumFeatureSymbol("LineMode", lineMode); |
| | | return result == IMVDefine.IMV_OK; |
| | | } |
| | | catch (Exception ex) |
| | | { |
| | | System.Diagnostics.Debug.WriteLine($"设置信å·çº¿æ¨¡å¼å¤±è´¥ï¼{ex.Message}"); |
| | | return false; |
| | | } |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 设置信å·çº¿çµå¹³ç¶æ |
| | | /// </summary> |
| | | public override bool SetLineStatus(IOLines line, LineStatus linestatus) |
| | | { |
| | | try |
| | | { |
| | | if (_camera == null || !_camera.IMV_IsOpen()) return false; |
| | | |
| | | // ä»
对è¾åºçº¿è·¯ææ |
| | | int result = _camera.IMV_SetEnumFeatureSymbol("LineSelector", line.ToString()); |
| | | if (result != IMVDefine.IMV_OK) return false; |
| | | |
| | | bool status = linestatus == LineStatus.Hight; |
| | | result = _camera.IMV_SetBoolFeatureValue("UserOutputValue", status); |
| | | return result == IMVDefine.IMV_OK; |
| | | } |
| | | catch (Exception ex) |
| | | { |
| | | System.Diagnostics.Debug.WriteLine($"设置信å·çº¿ç¶æå¤±è´¥ï¼{ex.Message}"); |
| | | return false; |
| | | } |
| | | } |
| | | |
| | | /// <summary> |
| | | /// è·åä¿¡å·çº¿çµå¹³ç¶æ |
| | | /// </summary> |
| | | public override bool GetLineStatus(IOLines line, out LineStatus lineStatus) |
| | | { |
| | | lineStatus = LineStatus.Low; |
| | | try |
| | | { |
| | | if (_camera == null || !_camera.IMV_IsOpen()) return false; |
| | | |
| | | int result = _camera.IMV_SetEnumFeatureSymbol("LineSelector", line.ToString()); |
| | | if (result != IMVDefine.IMV_OK) return false; |
| | | |
| | | bool status = false; |
| | | result = _camera.IMV_GetBoolFeatureValue("LineStatus", ref status); |
| | | if (result == IMVDefine.IMV_OK) |
| | | { |
| | | lineStatus = status ? LineStatus.Hight : LineStatus.Low; |
| | | return true; |
| | | } |
| | | return false; |
| | | } |
| | | catch (Exception ex) |
| | | { |
| | | System.Diagnostics.Debug.WriteLine($"è·åä¿¡å·çº¿ç¶æå¤±è´¥ï¼{ex.Message}"); |
| | | return false; |
| | | } |
| | | } |
| | | |
| | | /// <summary> |
| | | /// èªå¨ç½å¹³è¡¡ |
| | | /// </summary> |
| | | public override bool AutoBalanceWhite() |
| | | { |
| | | try |
| | | { |
| | | if (_camera == null || !_camera.IMV_IsOpen()) return false; |
| | | |
| | | if (_camera.IMV_FeatureIsValid("BalanceWhiteAuto")) |
| | | { |
| | | int result = _camera.IMV_SetEnumFeatureSymbol("BalanceWhiteAuto", "Once"); |
| | | return result == IMVDefine.IMV_OK; |
| | | } |
| | | return false; |
| | | } |
| | | catch (Exception ex) |
| | | { |
| | | System.Diagnostics.Debug.WriteLine($"èªå¨ç½å¹³è¡¡å¤±è´¥ï¼{ex.Message}"); |
| | | return false; |
| | | } |
| | | } |
| | | |
| | | #endregion |
| | | |
| | | #region ééå转æ¢è¾
婿¹æ³ |
| | | |
| | | /// <summary> |
| | | /// å¾åéé线ç¨å¤ç彿° |
| | | /// </summary> |
| | | private void GrabThreadProc() |
| | | { |
| | | while (_threadRunning) |
| | | { |
| | | IMVDefine.IMV_Frame frame = new IMVDefine.IMV_Frame(); |
| | | try |
| | | { |
| | | // è·åå¾å帧 |
| | | int result = _camera.IMV_GetFrame(ref frame, 1000); |
| | | |
| | | if (result == IMVDefine.IMV_OK) |
| | | { |
| | | // å¤çå¾å帧 |
| | | ProcessFrame(frame); |
| | | } |
| | | else |
| | | { |
| | | // å³ä½¿è·å失败ï¼ä¹å°è¯éæ¾å¸§ï¼é²æ¢SDKå
é¨ç¼åæ³é² |
| | | // 注æï¼frameæ¯æ¯æ¬¡æ°å»ºçï¼å¦æGetFrame没填å
ï¼è¿ééæ¾åºè¯¥æ¯å®å
¨çï¼è§SDKå®ç°èå®ï¼ |
| | | var tempFrame = frame; |
| | | _camera.IMV_ReleaseFrame(ref tempFrame); |
| | | |
| | | if ((uint)result != 0x80000001 && result != -119 && result != -102) // è¶
æ¶é误代ç |
| | | { |
| | | // éè¶
æ¶é误 |
| | | System.Diagnostics.Debug.WriteLine($"è·åå¾å帧失败ï¼é误ç ï¼{result}"); |
| | | Thread.Sleep(10); // åºéæ¶ç¨ä½çå¾
|
| | | } |
| | | } |
| | | } |
| | | catch (Exception ex) |
| | | { |
| | | System.Diagnostics.Debug.WriteLine($"éé线ç¨å¼å¸¸ï¼{ex.Message}"); |
| | | Thread.Sleep(10); |
| | | } |
| | | |
| | | Thread.Sleep(1); |
| | | } |
| | | } |
| | | |
| | | /// <summary> |
| | | /// å¤çå¾å帧 |
| | | /// </summary> |
| | | /// <param name="frame">å¾å帧</param> |
| | | private void ProcessFrame(IMVDefine.IMV_Frame frame) |
| | | { |
| | | try |
| | | { |
| | | // å°å¾åæ°æ®è½¬æ¢ä¸ºBitmap |
| | | Bitmap bitmap = ConvertFrameToBitmap(frame); |
| | | |
| | | if (bitmap != null) |
| | | { |
| | | // 触åå¾åééäºä»¶ |
| | | CameraEventArgs args = new CameraEventArgs(SN, bitmap); |
| | | ImageGrabbed?.Invoke(this, args); |
| | | |
| | | // æ´æ°åè°å¾å |
| | | CallBackImg = bitmap; |
| | | } |
| | | } |
| | | catch (Exception ex) |
| | | { |
| | | System.Diagnostics.Debug.WriteLine($"å¤çå¾å帧失败ï¼{ex.Message}"); |
| | | } |
| | | finally |
| | | { |
| | | // ç¡®ä¿æ 论å¦ä½é½éæ¾å¸§ï¼é²æ¢ç¼åå æ»¡ |
| | | var tempFrame = frame; |
| | | _camera.IMV_ReleaseFrame(ref tempFrame); |
| | | } |
| | | } |
| | | |
| | | /// <summary> |
| | | /// å°å¾å帧转æ¢ä¸ºBitmap |
| | | /// </summary> |
| | | /// <param name="frame">å¾å帧</param> |
| | | /// <returns>Bitmap对象</returns> |
| | | private Bitmap ConvertFrameToBitmap(IMVDefine.IMV_Frame frame) |
| | | { |
| | | try |
| | | { |
| | | Bitmap bitmap = null; |
| | | |
| | | switch (frame.frameInfo.pixelFormat) |
| | | { |
| | | case IMVDefine.IMV_EPixelType.gvspPixelMono8: |
| | | bitmap = CreateMono8Bitmap(frame); |
| | | break; |
| | | case IMVDefine.IMV_EPixelType.gvspPixelBGR8: |
| | | bitmap = CreateBgr8Bitmap(frame); |
| | | break; |
| | | default: |
| | | // å
¶ä»æ ¼å¼éè¦è½¬æ¢ |
| | | bitmap = ConvertToBGR8(frame); |
| | | break; |
| | | } |
| | | |
| | | return bitmap; |
| | | } |
| | | catch (Exception ex) |
| | | { |
| | | System.Diagnostics.Debug.WriteLine($"å¾åæ ¼å¼è½¬æ¢å¤±è´¥ï¼{ex.Message}"); |
| | | return null; |
| | | } |
| | | } |
| | | |
| | | /// <summary> |
| | | /// å建Mono8æ ¼å¼Bitmap |
| | | /// </summary> |
| | | private Bitmap CreateMono8Bitmap(IMVDefine.IMV_Frame frame) |
| | | { |
| | | Bitmap bitmap = new Bitmap((int)frame.frameInfo.width, (int)frame.frameInfo.height, PixelFormat.Format8bppIndexed); |
| | | |
| | | // 设置ç°åº¦è°è²æ¿ |
| | | ColorPalette palette = bitmap.Palette; |
| | | for (int i = 0; i < 256; i++) |
| | | { |
| | | palette.Entries[i] = Color.FromArgb(i, i, i); |
| | | } |
| | | bitmap.Palette = palette; |
| | | |
| | | // å¤å¶å¾åæ°æ® |
| | | BitmapData bmpData = bitmap.LockBits( |
| | | new Rectangle(0, 0, bitmap.Width, bitmap.Height), |
| | | ImageLockMode.WriteOnly, |
| | | bitmap.PixelFormat); |
| | | |
| | | // 使ç¨CopyMemory APIè¿è¡å
åå¤å¶ |
| | | CopyMemory(bmpData.Scan0, frame.pData, (uint)Math.Min(frame.frameInfo.size, (uint)(bmpData.Stride * bitmap.Height))); |
| | | |
| | | bitmap.UnlockBits(bmpData); |
| | | return bitmap; |
| | | } |
| | | |
| | | /// <summary> |
| | | /// å建BGR8æ ¼å¼Bitmap |
| | | /// </summary> |
| | | private Bitmap CreateBgr8Bitmap(IMVDefine.IMV_Frame frame) |
| | | { |
| | | Bitmap bitmap = new Bitmap((int)frame.frameInfo.width, (int)frame.frameInfo.height, PixelFormat.Format24bppRgb); |
| | | |
| | | BitmapData bmpData = bitmap.LockBits( |
| | | new Rectangle(0, 0, bitmap.Width, bitmap.Height), |
| | | ImageLockMode.WriteOnly, |
| | | bitmap.PixelFormat); |
| | | |
| | | // 使ç¨CopyMemory APIè¿è¡å
åå¤å¶ |
| | | CopyMemory(bmpData.Scan0, frame.pData, (uint)Math.Min(frame.frameInfo.size, (uint)(bmpData.Stride * bitmap.Height))); |
| | | |
| | | bitmap.UnlockBits(bmpData); |
| | | return bitmap; |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 转æ¢ä¸ºBGR8æ ¼å¼ |
| | | /// </summary> |
| | | private Bitmap ConvertToBGR8(IMVDefine.IMV_Frame frame) |
| | | { |
| | | IMVDefine.IMV_PixelConvertParam convertParam = new IMVDefine.IMV_PixelConvertParam |
| | | { |
| | | nWidth = frame.frameInfo.width, |
| | | nHeight = frame.frameInfo.height, |
| | | ePixelFormat = frame.frameInfo.pixelFormat, |
| | | pSrcData = frame.pData, |
| | | nSrcDataLen = frame.frameInfo.size, |
| | | nPaddingX = frame.frameInfo.paddingX, |
| | | nPaddingY = frame.frameInfo.paddingY, |
| | | eBayerDemosaic = IMVDefine.IMV_EBayerDemosaic.demosaicBilinear, |
| | | eDstPixelFormat = IMVDefine.IMV_EPixelType.gvspPixelBGR8, |
| | | nDstBufSize = frame.frameInfo.width * frame.frameInfo.height * 3 |
| | | }; |
| | | |
| | | IntPtr dstBuffer = Marshal.AllocHGlobal((int)convertParam.nDstBufSize); |
| | | convertParam.pDstBuf = dstBuffer; |
| | | |
| | | try |
| | | { |
| | | int result = _camera.IMV_PixelConvert(ref convertParam); |
| | | if (result == IMVDefine.IMV_OK) |
| | | { |
| | | return CreateBgr8BitmapFromBuffer(dstBuffer, frame.frameInfo.width, frame.frameInfo.height); |
| | | } |
| | | return null; |
| | | } |
| | | finally |
| | | { |
| | | Marshal.FreeHGlobal(dstBuffer); |
| | | } |
| | | } |
| | | |
| | | /// <summary> |
| | | /// ä»ç¼å²åºå建BGR8 Bitmap |
| | | /// </summary> |
| | | private Bitmap CreateBgr8BitmapFromBuffer(IntPtr buffer, uint width, uint height) |
| | | { |
| | | Bitmap bitmap = new Bitmap((int)width, (int)height, PixelFormat.Format24bppRgb); |
| | | |
| | | BitmapData bmpData = bitmap.LockBits( |
| | | new Rectangle(0, 0, bitmap.Width, bitmap.Height), |
| | | ImageLockMode.WriteOnly, |
| | | bitmap.PixelFormat); |
| | | |
| | | // 使ç¨CopyMemory APIè¿è¡å®å
¨çå
åå¤å¶ |
| | | CopyMemory(bmpData.Scan0, buffer, (uint)(width * height * 3)); |
| | | |
| | | bitmap.UnlockBits(bmpData); |
| | | return bitmap; |
| | | } |
| | | |
| | | /// <summary> |
| | | /// å°è§¦åæºæä¸¾è½¬æ¢ä¸ºå符串 |
| | | /// </summary> |
| | | private string GetTriggerSourceString(TriggerSource source) |
| | | { |
| | | return source switch |
| | | { |
| | | TriggerSource.Software => "Software", |
| | | TriggerSource.Line0 => "Line0", |
| | | TriggerSource.Line1 => "Line1", |
| | | TriggerSource.Line2 => "Line2", |
| | | TriggerSource.Line3 => "Line3", |
| | | TriggerSource.Line4 => "Line4", |
| | | TriggerSource.Line5 => "Line5", |
| | | _ => "Software" |
| | | }; |
| | | } |
| | | |
| | | /// <summary> |
| | | /// å°å符串转æ¢ä¸ºè§¦åæºæä¸¾ |
| | | /// </summary> |
| | | private TriggerSource GetTriggerSourceFromString(string source) |
| | | { |
| | | return source switch |
| | | { |
| | | "Software" => TriggerSource.Software, |
| | | "Line0" => TriggerSource.Line0, |
| | | "Line1" => TriggerSource.Line1, |
| | | "Line2" => TriggerSource.Line2, |
| | | "Line3" => TriggerSource.Line3, |
| | | "Line4" => TriggerSource.Line4, |
| | | "Line5" => TriggerSource.Line5, |
| | | _ => TriggerSource.Software |
| | | }; |
| | | } |
| | | |
| | | #endregion |
| | | |
| | | |
| | | #region IDisposableå®ç° |
| | | |
| | | private bool _disposed = false; |
| | | |
| | | protected virtual void Dispose(bool disposing) |
| | | { |
| | | if (!_disposed) |
| | | { |
| | | if (disposing) |
| | | { |
| | | // éæ¾æç®¡èµæº |
| | | } |
| | | |
| | | // éæ¾éæç®¡èµæº |
| | | CloseDevice(); |
| | | |
| | | _disposed = true; |
| | | } |
| | | } |
| | | |
| | | public override void Dispose() |
| | | { |
| | | Dispose(true); |
| | | GC.SuppressFinalize(this); |
| | | } |
| | | |
| | | #endregion |
| | | } |
| | | } |