開發環境 Visual Studio 2010 C# WindowsForm 應用程式
webcam啟動是使用EmguCV
先介紹EmguCV 可用於人臉辨識和影像, 其實它是基於 OpenCV 所延伸出的一套library,特別為 .Net平台而設計。
2012/08/06 補充 執行本範例請使用emgucv-windows-x86 2.3.0.1416.exe 版本
EmguCV最新版本
本範例EmguCV版本
emgucv-windows-x86 2.3.0.1416.exe
安裝完需再添加環境變數(加入完整路徑 預設C:\Emgu\emgucv-windows-x86 2.3.0.1416\bin),步驟如下
1.我的電腦右鍵內容 ---> 進階系統設定 ---> 進階 ---> 環境變數
2.系統變數 ---> 變數尋找到Path ---> 編輯
3.將EmguCV 安裝完的完整路徑加進去,如為預設請加入C:\Emgu\emgucv-windows-x86 2.3.0.1416\bin ※Windows環境變數需以分號區隔 Linux區隔為冒號
開啟一個Form新專案 加入一個pictureBox 三個button
版面設計
加入四個參考 Emgu.CV.dll,Emgu.CV.ML.dll,Emgu.CV.UI.dll,Emgu.Util.dll (該dll放於EmguCV安裝完的bin底下)
載入所需的
全區域變數宣告
//攝影機的變量
private Capture _capture;
//判斷是否啟動webcam的frame旗標
private bool _captureInProgress = false;
private void Form1_Load(object sender, EventArgs e)
{
//預設使用第一台的webcam
_capture = new Capture(0);
}
//frame的處裡事件
void Application_Idle(object sender, EventArgs e)
{
Image<Bgr, Byte> frame = _capture.QueryFrame();
pictureBox1.Image = frame.ToBitmap();
}
//啟動webcam
private void button1_Click(object sender, EventArgs e)
{
//如果webcam沒啟動
if (_capture == null)
{
try
{
//打開預設的webcam
_capture = new Capture();
}
catch (NullReferenceException excpt)
{
MessageBox.Show(excpt.Message);
}
}
//webcam啟動
if (_capture != null)
{
//frame啟動
if (_captureInProgress)
{ //stop the capture
_captureInProgress = false;
button1.Text = "开始";
Application.Idle -= Application_Idle;
}
//frame關閉
else
{
//start the capture
_captureInProgress = true;
button1.Text = "结束";
Application.Idle += Application_Idle;
}
}
}
//錄製影像
private void button2_Click(object sender, EventArgs e)
{
_capture = new Capture();
if (_capture == null)
{
MessageBox.Show("can't find a camera", "error");
}
Image<Bgr, byte> temp = _capture.QueryFrame();
SaveFileDialog SaveFileDialog1 = new SaveFileDialog();
SaveFileDialog1.FileName = DateTime.Now.ToString("yyyyMMddhhmmss");
SaveFileDialog1.Filter = "Image Files(*.avi)|*.avi|All files (*.*)|*.*";
if (SaveFileDialog1.ShowDialog() == DialogResult.OK)
{
MessageBox.Show("開始錄製,按ESC結束錄製");
}
VideoWriter video = new VideoWriter(SaveFileDialog1.FileName, CvInvoke.CV_FOURCC('X', 'V', 'I', 'D'), 20, 800, 600, true);
while (temp != null)
{
CvInvoke.cvShowImage("camera", temp.Ptr);
temp = _capture.QueryFrame();
int c = CvInvoke.cvWaitKey(20);
video.WriteFrame<Bgr, byte>(temp);
if (c == 27) break;
}
video.Dispose();
CvInvoke.cvDestroyWindow("camera");
//錄影完需將影像停止不然會出錯
_captureInProgress = false;
button1.Text = "開始";
Application.Idle -= Application_Idle;
}
//關閉程式
private void button3_Click(object sender, EventArgs e)
{
_capture.Dispose();
Application.Exit();
}
參考資料:
http://blog.csdn.net/puncsky/article/details/7176810
http://apps.hi.baidu.com/share/detail/59126928
範例下載:EmguCV

您好: 我測試了程式在 video.WriteFrame(temp);
該段出現未處理的訊息,
嘗試讀取或寫入受保護的記憶體。這通常表示其他記憶體已損毀。
是否能指點是哪方面有問題呢? 非常謝謝你!
hi wei: 你可以嘗試參考這篇: http://stackoverflow.com/questions/9915001/slanted-video-in-opencv 修改這行code VideoWriter video = new VideoWriter(SaveFileDialog1.FileName, CvInvoke.CV_FOURCC('X', 'V', 'I', 'D'), 20, 800, 600, true);
HI:您好 我執行了您的程式後出現這問題 //預設使用第一台的webcam _capture = new Capture(0); 'Emgu.CV.CvInvoke' 的型別初始設定式發生例外狀況。 該怎麼解決呢?
Hi: 請問你有正確設定好環境變數嗎? 如沒有請照本篇的方式設定好環境變數。
您好: 環境變數也設跟您一樣了 還是一樣的情形 另外一提抓取攝影機的函數為何呢?
_capture = new Capture();
另外找到 Message=無法載入 DLL 'opencv_core240': 找不到指定的模組。 (發生例外狀況於 HRESULT: 0x8007007E) Source=Emgu.CV TypeName="" StackTrace: 於 Emgu.CV.CvInvoke.cvRedirectError(CvErrorCallback errorHandler, IntPtr userdata, IntPtr prevUserdata) 於 Emgu.CV.CvInvoke..cctor() InnerException: 這問題是什麼呢?
Hi: 我猜可能是你的作業系統版本問題 請參考下面這篇 http://sharedderrick.blogspot.tw/2008/10/x64-sql-server-compact-35-dll.html
我作業系統是32位元 版本是Windows Vista Business 另外一提 _caputure = new Capture(); 這函式適用於所有的webcam嗎? 還是可以用抓取COM使用
是不是適用於全部webcam這點我不清楚, 或許你可以試看看是不是webcam的問題, 是否可以抓COM我沒用過,所以幫不上忙, 建議你使用這篇看能不能正常先顯示出webcam的影像 http://blog.kenyang.net/2012/03/c-webcam-using-emgu.html ※使用本篇範例需先啟動webcam 才能執行錄製動作。
您好: 兩篇都用了 還是一樣 另一篇的opencv_core231.dll opencv_highgui231.dll 我是opencv_core240.dll opencv_highgui240.dll 有影響嗎? 我用的攝影機是QuickCam10
Hi: 那只是opencv版本應該沒差, 我在猜會不會是作業系統的問題, 因為我是使用Windows 7。
您好: 我參考了這篇 http://www.dotblogs.com.tw/chou/archive/2009/06/13/8812.aspx 照他的用問題也一樣 但是直接抓他的範例就能使用了 怎麼會這樣呢
Hi: 這我也不太清楚。
您好 我想請教您一下 Imagebox 跟 pictureBox有什麼差別呢?
ImageBox大致上跟PictureBox功能是類似的, 只不過在ImageBox執行時,能使用滑鼠右鍵,控制圖片的大小或載入等等。 請參考這篇 http://www.emgu.com/wiki/index.php/ImageBox
ImageBox不屬於點陣圖 那我如何才能抓出他的pixel值呢?
不好意思,我也是初學者,所以幫不上你的忙XD 不過我有找到幾篇文章看能不能幫上你的忙。 http://stackoverflow.com/questions/9928662/how-can-i-get-a-emgucv-imagebox-image http://www.emgu.com/wiki/index.php/Setting_up_EMGU_C_Sharp
可以請問您一下嗎 要怎麼透過C#控制webcam的曝光 低補償等等 或是設定環境 排除一些環境變化等等呢?
這部分我沒有研究過... 幫不上忙,不好意思。
請問我用vb.net執行時會出現 Emgu.CV.CvInvoke' 的型別初始設定式發生例外狀況 然後我到資料夾裡直接執行exe 沒有出現錯誤 而且功能還正常... 請問要怎麼改善啊? emgucv還真難搞懂 = =
請問在錄影開始時,要如何能顯示在原視窗?
這我也沒試過,可能要請你自己試看看。
請問這個方法錄製的影片只能是.avi格式嗎? 還是有其他辦法修改成.mp4之類的?
各位老師我在將此教學轉寫成 UNITY 的程式碼遇到以下錯誤 我的程式碼: using UnityEngine; using System.Collections; using System.IO; using System; using Emgu.CV; using Emgu.CV.Structure; using Emgu.Util; using System.Threading; using Emgu.CV.CvEnum; public class EmhuCV_text : MonoBehaviour { private Capture _capture; private bool _captureInProgress = true; public GameObject pic_view; Texture webcam_texture; string _string_DateTime; string _string_AVIName; // Use this for initialization void Start () { _string_AVIName = "text"; _capture = new Capture(); Image frame = _capture.QueryFrame();
webcam_texture = pic_view.GetComponent().material.mainTexture;
if (_capture != null)
{
if (_captureInProgress)
{
_captureInProgress = false;
print("開始");
//Application.Idle -= Application_Idle;
}
else
{
_captureInProgress = true;
print("結束");
}
}
}
// Update is called once per frame
void Update () {
}
void OnGUI()
{
if (GUI.Button(new Rect(0, 0, 100, 50), "關閉"))
{
_captureInProgress = false;
print("關閉");
_capture.Dispose();
}
if (GUI.Button(new Rect(100, 0, 100, 50), "錄製"))
{
// _capture = new Capture();
Image temp = _capture.QueryFrame();
_string_DateTime = DateTime.Now.ToString("yyyyMMddhhmmss");
VideoWriter video = new VideoWriter(_string_AVIName, CvInvoke.CV_FOURCC('X', 'V', 'I', 'D'), 20, 800, 600, true);
while(temp !=null)
{
CvInvoke.cvShowImage("camera", temp.Ptr);
temp = _capture.QueryFrame();
video.WriteFrame(temp);
int c = CvInvoke.cvWaitKey(20);
if (c == 27) break;
}
video.Dispose();
CvInvoke.cvDestroyWindow("camera");
}
}
}
========== 下方為按下 "錄製' 按鈕後出現的錯誤訊息=============
InvalidOperationException: Unable to write frame to the video writer
Emgu.CV.VideoWriter.WriteFrame[Bgr,Byte] (Emgu.CV.Image`2 frame)
EmhuCV_text.OnGUI () (at Assets/script/EmhuCV_text.cs:68)
錯在這個指令碼 video.WriteFrame(temp);
以上該怎解決的? 感謝各位老師。
您好~ 照您的程式撰寫後編譯無誤 但執行起來卻無畫面 請問是VB沒連接到webcam嗎? 那該如何才能連上呢?
請問環境變數有設定完成了嗎
我的環境變數那邊,編輯的功能無法點選,是因為權限的問題嗎,請問有其他可以取代更改環境變數嗎?
有可能是權限的問題 你的作業系統是什麼
老師請問2個問題 1.如何能在錄制的影片內加入時間戳 2.如何加入多台webcam 的功能, 會自動偵測 webcam 數量