新增專案名稱 “CameraCapture”
加入 references Emgu.CV Emgu.CV.UI Emgu.Util from directory
C:\Emgu\emgucv-windows-universal-cuda 3.0.0.2158\bin
1: using System;
2: using System.Collections.Generic;
3: using System.ComponentModel;
4: using System.Data;
5: using System.Drawing;
6: using System.Linq;
7: using System.Text;
8: using System.Windows.Forms;
9: 10: using Emgu.CV;
11: using Emgu.CV.CvEnum;
12: using Emgu.CV.Structure;
13: using Emgu.Util;
Add variables
1: private Capture m_capture;
2: private bool m_captureInProgress;
3: private int m_camIndex = 1;
專案新增x64目錄並加入C:\Emgu\emgucv-windows-universal-cuda 3.0.0.2158\bin\x64目錄下所有dll檔案
輸入*.dll按下Enter鍵, 複選全部檔案(方法1:CTRL+a鍵;
方法2:滑鼠點選第一個dll檔案, 按下Shift鍵不放, 點選最後一個dll檔案)
設定剛才加入的dll檔案屬性(複製到輸出目錄 = 有更新時才複製)
加入x64目錄下dll有個好處, 可以將Release目錄複製到一台沒有安裝Emgu電腦下執行,
缺點是每一個專案都會自己一份dll, 占用不少硬體空間(600多MB)
另一種方式是增加系統變數方式, 讓系統找得到對應的dll檔案即可
==========================================================
設定攝影機FrameGrabber副程式, 框架如下
1: private void FrameGrabber(object sender, EventArgs e)
2: { 3: }定義5張Mat格式變數colorFrame, grayFrame, smallGrayFrame, smoothGrayFrame, cannyFrame
1: private void FrameGrabber(object sender, EventArgs e)
2: {3: using(Mat colorFrame = new Mat())
4: using(Mat grayFrame = new Mat())
5: using(Mat smallGrayFrame = new Mat())
6: using (Mat smoothGrayFrame = new Mat())
7: using (Mat cannyFrame = new Mat())
8: { 9: m_capture.Retrieve(colorFrame, 0); 10: CvInvoke.CvtColor(colorFrame, grayFrame, ColorConversion.Bgr2Gray); 11: CvInvoke.PyrDown(grayFrame, smallGrayFrame); 12: CvInvoke.PyrUp(smallGrayFrame, smoothGrayFrame); 13: CvInvoke.Canny(smoothGrayFrame, cannyFrame, 100, 60); 14: 15: captureImageBox.Image = colorFrame; 16: grayscaleImageBox.Image = grayFrame; 17: smoothedGrayscaleImageBox.Image = smoothGrayFrame; 18: cannyImageBox.Image = cannyFrame; 19: } 20: }上述local變數使用using會有一個問題, 當該物件被資源釋放時(IDISPOSABLE),
有可能同時又被指派至imageBox, 這時候就會跳出錯誤訊息
測試後改以下列方式(不使用using)
1: 2: Mat colorFrame = new Mat();
3: Mat grayFrame = new Mat();
4: Mat smallGrayFrame = new Mat();
5: Mat smoothGrayFrame = new Mat();
6: Mat cannyFrame = new Mat();
7: { 8: m_capture.Retrieve(colorFrame, 0); 9: CvInvoke.CvtColor(colorFrame, grayFrame, ColorConversion.Bgr2Gray); 10: CvInvoke.PyrDown(grayFrame, smallGrayFrame); 11: CvInvoke.PyrUp(smallGrayFrame, smoothGrayFrame); 12: CvInvoke.Canny(smoothGrayFrame, cannyFrame, 100, 60);13: try
14: { 15: captureImageBox.Image = colorFrame; 16: grayscaleImageBox.Image = grayFrame; 17: smoothedGrayscaleImageBox.Image = smoothGrayFrame; 18: cannyImageBox.Image = cannyFrame; 19: }20: catch (Exception exception)
21: { 22: MessageBox.Show(exception.Message); 23: } 24: GC.Collect(); 25: }使用using版本,CameraCapture記憶體固定大概33~35MB,
如果不使用using版本, 記憶體可能會飆高到500~700MB甚至更高, 然後才被釋放,
建議可以加入GC.Collect();記憶體固定大概也可以維持在33~35MB
附帶一提, GC.Release會花一些時間, 不如將這些變數拉高至Form1成員變數
這樣就不會一直創建/釋放物件
1: public partial class Form1 : Form
2: {3: private Capture m_capture;
4: private bool m_captureInProgress;
5: private int m_camIndex = 1;
6: Mat colorFrame = new Mat();
7: Mat grayFrame = new Mat();
8: Mat smallGrayFrame = new Mat();
9: Mat smoothGrayFrame = new Mat();
10: Mat cannyFrame = new Mat();
DoubleBufferOn
1: private void DoubleBufferOn()
2: {3: SetStyle(ControlStyles.AllPaintingInWmPaint, true);
4: SetStyle(ControlStyles.OptimizedDoubleBuffer, true);
5: UpdateStyles(); 6: }Form1 Constructor
1: public Form1()
2: { 3: InitializeComponent(); 4: DoubleBufferOn(); 5: 6: CvInvoke.UseOpenCL = false;
7: try
8: {9: m_capture = new Capture(m_camIndex);
10: this.DoubleBuffered = true;
11: m_capture.ImageGrabbed += new EventHandler(FrameGrabber);
12: }13: catch (Exception exception)
14: { 15: MessageBox.Show(exception.Message); 16: } 17: }Start/Stop Camera
1: private void captureButton_Click(object sender, EventArgs e)
2: {3: if (m_capture != null)
4: {5: if (m_captureInProgress)
6: {7: captureButton.Text = "Start Capture";
8: m_capture.Pause(); 9: }10: else
11: {12: captureButton.Text = "Stop Capture";
13: m_capture.Start(); 14: } 15: m_captureInProgress = !m_captureInProgress; 16: } 17: }Flip Horizontally
1: private void flipHorizontalButton_Click(object sender, EventArgs e)
2: { 3: m_capture.FlipHorizontal = !m_capture.FlipHorizontal; 4: }Flip Virtically
1: private void flipVerticalButton_Click(object sender, EventArgs e)
2: { 3: m_capture.FlipVertical = !m_capture.FlipVertical; 4: }範例程式: CameraCapture
參考資料
2. OpenCL







留言列表
