using System; using System.Collections.Generic; using System.Drawing; using System.Linq; using System.Threading; using System.Windows.Forms; using ThridLibray; namespace _1_5相機SDK圖像采集 { public class Camera { List<IGrabbedRawData> m_frameList = new List<IGrabbedRawData>(); /* 圖像緩存列表 */ Thread renderThread = null; /* 顯示線程 */ bool m_bShowLoop = true; /* 線程控制變量 */ Mutex m_mutex = new Mutex(); /* 鎖,保證多線程安全 */ public event Action<Bitmap> NewImage; public Camera() { if (null == renderThread) { renderThread = new Thread(new ThreadStart(ShowThread)); renderThread.IsBackground = true; renderThread.Start(); } } /* 轉碼顯示線程 */ private void ShowThread() { while (m_bShowLoop) { if (m_frameList.Count == 0) { Thread.Sleep(1); continue; } /* 圖像隊列取最新幀 */ m_mutex.WaitOne(); IGrabbedRawData frame = m_frameList.ElementAt(0); m_frameList.RemoveAt(0); m_frameList.Clear(); m_mutex.ReleaseMutex(); /* 主動調用回收垃圾 */ GC.Collect(); try { /* 圖像轉碼成bitmap圖像 */ var bitmap = frame.ToBitmap(false); if (NewImage!=null) { NewImage(bitmap); } } catch (Exception exception) { Catcher.Show(exception); } } } /* 設備對象 */ private IDevice m_dev; /* 相機打開回調 */ private void OnCameraOpen(object sender, EventArgs e) { MessageBox.Show("相機已打開!"); } /* 相機關閉回調 */ private void OnCameraClose(object sender, EventArgs e) { MessageBox.Show("相機已關閉!"); } /* 相機丟失回調 */ private void OnConnectLoss(object sender, EventArgs e) { m_dev.ShutdownGrab(); m_dev.Dispose(); m_dev = null; } public void btnOpen() { try { /* 設備搜索 */ List<IDeviceInfo> li = Enumerator.EnumerateDevices(); if (li.Count > 0) { /* 獲取搜索到的第一個設備 */ m_dev = Enumerator.GetDeviceByIndex(0); /* 注冊鏈接事件 */ m_dev.CameraOpened += OnCameraOpen; m_dev.CameraClosed += OnCameraClose; /* 打開設備 */ if (!m_dev.Open()) { MessageBox.Show(@"連接相機失敗"); return; } /* 打開Software Trigger */ m_dev.TriggerSet.Open(TriggerSourceEnum.Software); /* 設置圖像格式 */ using (IEnumParameter p = m_dev.ParameterCollection[ParametrizeNameSet.ImagePixelFormat]) { p.SetValue("Mono8"); } /* 設置曝光 */ using (IFloatParameter p = m_dev.ParameterCollection[ParametrizeNameSet.ExposureTime]) { p.SetValue(1000); } /* 設置增益 */ using (IFloatParameter p = m_dev.ParameterCollection[ParametrizeNameSet.GainRaw]) { p.SetValue(1.0); } /* 設置緩存個數為8(默認值為16) */ m_dev.StreamGrabber.SetBufferCount(8); /* 注冊碼流回調事件 */ m_dev.StreamGrabber.ImageGrabbed += OnImageGrabbed; /* 開啟碼流 */ if (!m_dev.GrabUsingGrabLoopThread()) { MessageBox.Show(@"開啟碼流失敗"); return; } } } catch (Exception exception) { Catcher.Show(exception); } } /* 碼流數據回調 */ private void OnImageGrabbed(Object sender, GrabbedEventArgs e) { m_mutex.WaitOne(); m_frameList.Add(e.GrabResult.Clone()); m_mutex.ReleaseMutex(); } /* 停止碼流 */ public void btnClose() { try { if (m_dev == null) { throw new InvalidOperationException("Device is invalid"); } m_dev.StreamGrabber.ImageGrabbed -= OnImageGrabbed; /* 反注冊回調 */ m_dev.ShutdownGrab(); /* 停止碼流 */ m_dev.Close(); /* 關閉相機 */ } catch (Exception exception) { Catcher.Show(exception); } } /* 窗口關閉 */ public void OnClosed(EventArgs e) { if (m_dev != null) { m_dev.Dispose(); m_dev = null; } m_bShowLoop = false; renderThread.Join(); } /* 執行軟觸發 */ public void SoftwareTrigger() { if (m_dev == null) { throw new InvalidOperationException("Device is invalid"); } try { m_dev.ExecuteSoftwareTrigger(); } catch (Exception exception) { Catcher.Show(exception); } } } }