天天看點

C# 利用 OpenCV 進行視訊捕獲 (筆記)

這個項目是關于如何從網絡攝像頭或者視訊檔案(*.AVI)中捕獲視訊的,這個項目是用C#和OPENCV編寫的。

這将有助于那些喜歡C#和OpenCV環境的人。這個程式完全基于Visual Studio 2010 version C#.NET環境。這個程式展示了怎樣用C#.NET環境的Visual Studio 2010 IDE編寫OpenCV,這個程式是一個怎樣用Visual Studio 2010,C#.NET建立程式的例子。

在這篇文章中,我解釋了怎樣配置Visual Studio 2010,一種配置計算機環境變量EmguCV2.4.9以便運作OpenCV程式的步驟。

C# 利用 OpenCV 進行視訊捕獲 (筆記)

EmguCV:讓我們開始工作吧。。。

EmguCV 是一個跨平台的運作OpenCV圖形庫的殼。它允許從.NET語言例如C#,VB,VC++中調用OpenCV函數,這個殼可以用Mono編譯,在Windows,Linux,Mac OS X,iPhone,iPad 和Android 裝置中運作。

EmguCV是用C#編寫的。可以在Mono中編譯,是以它可以在任何Mono支援的平台上運作,包括 Linux, Mac and Android。

C# 利用 OpenCV 進行視訊捕獲 (筆記)

<a target="_blank" href="http://my.oschina.net/pou">pou</a>

翻譯于 2年前

2人頂

第 1 步: 安裝 EmguCV 2.4.9

下載下傳 EmguCV 2.4.9 版本. 将它安裝在 c:\ 磁盤 位置, 不要改變路徑, 使用預設的路徑“C:\Emgu\emgucv-windows-universal-gpu2.4.9.1847”.

C# 利用 OpenCV 進行視訊捕獲 (筆記)

安裝路徑 – “C:\Emgu\emgucv-windows-universal-gpu2.4.9.1847”.

C# 利用 OpenCV 進行視訊捕獲 (筆記)

所有的框框都選上,全包安裝.

第 2 步: 設定環境變量:

C# 利用 OpenCV 進行視訊捕獲 (筆記)

在使用者和系統變量中設定如下的三個路徑.

C:\Emgu\emgucv-windows-universal-gpu 2.4.9.1847\bin;

C:\Emgu\emgucv-windows-universal-gpu 2.4.9.1847\bin\x64;

C:\Emgu\emgucv-windows-universal-gpu 2.4.9.1847\bin\x86;

第 3 步: 配置 Visual Studio 2010:

建立一個新的 Windows Application 項目,命名為‘Two Layer’.

選擇引用, 右鍵點選添加引用.

C# 利用 OpenCV 進行視訊捕獲 (筆記)

選擇 Browse 頁籤, 找到“C:\Emgu\emgucv-windows-universal-gpu2.4.9.1847\bin”, 選擇“Emgu.CV.dll”,”Emgu.CV.UI.dll”,”Emgu.Util.dll” 三個檔案, 并點選ok.

C# 利用 OpenCV 進行視訊捕獲 (筆記)

引用就會在Solution Explorer中出現.

C# 利用 OpenCV 進行視訊捕獲 (筆記)
C# 利用 OpenCV 進行視訊捕獲 (筆記)

<a target="_blank" href="http://my.oschina.net/xuleo">leoxu</a>

0人頂

捕獲視訊功能,捕獲視訊有兩種方式,一種是從錄影機捕獲,第二種是從視訊檔案捕獲。接下來的部分,代碼會向你展示如果從錄影機捕獲視屏.

在這一節中, 捕獲, FRAME PER SECOND 設定為 30 FPS, 視訊檔案捕獲的高和寬分别設定為 240, 320 . 然後video_seek

被初始化為零 '0', 這個視訊搜尋控制會在視訊限制的低位和高位之間搜尋視訊.

下面的語句在應用程式中最有用. 它有點像多線程. 當應用程式進入到空閑狀态,"ProcessFrame" 就會一直調用直到視訊幀結束或者直到幀不為 'null'.

1

<code>Application.Idle += ProcessFrame;</code>

在從視訊檔案捕獲的代碼中,我們需要總幀數來設定視訊搜尋控制的上限. FOURCC 被用來找到多媒體的編碼解碼器名稱.

C# 利用 OpenCV 進行視訊捕獲 (筆記)

<code>#region cameracapture</code>

<code>   </code><code>if</code> <code>(comboBox1.Text == </code><code>"Capture From Camera"</code><code>)</code>

<code>   </code><code>{</code>

<code>     </code><code>try</code>

<code>     </code><code>{</code>

<code>       </code><code>_capture = </code><code>null</code><code>;</code>

<code>       </code><code>_capture = </code><code>new</code> <code>Capture(0);</code>

<code>       </code><code>_capture.SetCaptureProperty(Emgu.CV.CvEnum.CAP_PROP.CV_CAP_PROP_FPS, 30);</code>

<code>       </code><code>_capture.SetCaptureProperty(Emgu.CV.CvEnum.CAP_PROP.CV_CAP_PROP_FRAME_HEIGHT, 240);</code>

<code>       </code><code>_capture.SetCaptureProperty(Emgu.CV.CvEnum.CAP_PROP.CV_CAP_PROP_FRAME_WIDTH, 320);</code>

<code>       </code><code>Time_Label.Text = </code><code>"Time: "</code><code>;</code>

<code>       </code><code>Codec_lbl.Text = </code><code>"Codec: "</code><code>;</code>

<code>       </code><code>Frame_lbl.Text = </code><code>"Frame: "</code><code>;</code>

<code>       </code><code>webcam_frm_cnt = 0;</code>

<code>       </code><code>cam = 1;</code>

<code>       </code><code>Video_seek.Value = 0;</code>

<code>       </code><code>Application.Idle += ProcessFrame;</code>

<code>       </code><code>button1.Text = </code><code>"Stop"</code><code>;</code>

<code>       </code><code>comboBox1.Enabled = </code><code>false</code><code>;</code>

<code>     </code><code>}</code>

<code>     </code><code>catch</code> <code>(NullReferenceException excpt)</code>

<code>        </code><code>MessageBox.Show(excpt.Message);</code>

<code>   </code><code>}</code>

<code>#endregion cameracapture</code>

<code>#region filecapture</code>

<code>   </code><code>if</code> <code>(comboBox1.Text == </code><code>"Capture From File"</code><code>)</code>

<code>     </code><code>openFileDialog1.Filter = </code><code>"MP4|*.mp4"</code><code>;</code>

<code>     </code><code>openFileDialog1.FileName = </code><code>""</code><code>;</code>

<code>     </code><code>if</code> <code>(openFileDialog1.ShowDialog() == DialogResult.OK)</code>

<code>      </code><code>try</code>

<code>      </code><code>{</code>

<code>        </code><code>_capture = </code><code>null</code><code>;</code>

<code>        </code><code>_capture = </code><code>new</code> <code>Capture(openFileDialog1.FileName);</code>

<code>        </code><code>_capture.SetCaptureProperty(Emgu.CV.CvEnum.CAP_PROP.CV_CAP_PROP_FRAME_HEIGHT, 240);</code>

<code>        </code><code>_capture.SetCaptureProperty(Emgu.CV.CvEnum.CAP_PROP.CV_CAP_PROP_FRAME_WIDTH, 320);</code>

<code>        </code><code>FrameRate = _capture.GetCaptureProperty(Emgu.CV.CvEnum.CAP_PROP.CV_CAP_PROP_FPS);</code>

<code>        </code><code>TotalFrames = _capture.GetCaptureProperty(Emgu.CV.CvEnum.CAP_PROP.CV_CAP_PROP_FRAME_COUNT);</code>

<code>        </code><code>codec_double = _capture.GetCaptureProperty(Emgu.CV.CvEnum.CAP_PROP.CV_CAP_PROP_FOURCC);</code>

<code>        </code><code>string</code> <code>s = </code><code>new</code> <code>string</code><code>(System.Text.Encoding.UTF8.GetString</code>

<code>        </code><code>(BitConverter.GetBytes(Convert.ToUInt32(codec_double))).ToCharArray());</code>

<code>        </code><code>Codec_lbl.Text = </code><code>"Codec: "</code> <code>+ s;</code>

<code>        </code><code>cam = 0;</code>

<code>        </code><code>Video_seek.Minimum = 0;</code>

<code>        </code><code>Video_seek.Maximum = (</code><code>int</code><code>)TotalFrames - 1;</code>

<code>        </code><code>Application.Idle += ProcessFrame;</code>

<code>        </code><code>button1.Text = </code><code>"Stop"</code><code>;</code>

<code>        </code><code>comboBox1.Enabled = </code><code>false</code><code>;</code>

<code>      </code><code>}</code>

<code>      </code><code>catch</code> <code>(NullReferenceException excpt)</code>

<code>         </code><code>MessageBox.Show(excpt.Message);</code>

<code>    </code><code>}</code>

<code>  </code><code>}</code>

<code>#endregion filecapture</code>

下面的函數用來處理幀. 幀處理可以提取出一些詳細資訊,如幀的編号,時間軸,總的幀數等. 這個函數展示了圖檔盒子中的圖像序列. 幀可以被轉換成位元組數組. 這個位元組資料可以被轉換成每一幀的16進制值. 然後那些十六進制值被存到數組中做進一步的處理. 從裝置或者視訊檔案捕獲的視訊中提取目前幀.

<code>frame = _capture.QueryFrame();</code>

幀被轉換成 bitmap 并被指派給圖檔盒子用于展示 .  

<code>pictureBox1.Image = frame.ToBitmap();</code>

函數在按幀率劃分的特定時間休眠.  

<a target="_blank" href="http://www.oschina.net/translate/video-capture-using-opencv-with-csharp#">?</a>

<code>Thread.Sleep((</code><code>int</code><code>)(1000.0 / FrameRate));</code>

幀被轉換成位元組數組.

這個位元組資料被轉換成每一幀的16進制值. 然後那些十六進制值被存到數組中做進一步的處理.

<code>private</code> <code>void</code> <code>ProcessFrame(</code><code>object</code> <code>sender, EventArgs arg)</code>

<code>{</code>

<code> </code><code>try</code>

<code>  </code><code>{</code>

<code>    </code><code>Framesno = _capture.GetCaptureProperty(Emgu.CV.CvEnum.CAP_PROP.CV_CAP_PROP_POS_FRAMES);</code>

<code>    </code><code>frame = _capture.QueryFrame();</code>

<code>    </code><code>if</code> <code>(frame != </code><code>null</code><code>)</code>

<code>    </code><code>{</code>

<code>        </code><code>pictureBox1.Image = frame.ToBitmap();</code>

<code>        </code><code>if</code> <code>(cam == 0)</code>

<code>        </code><code>{</code>

<code>          </code><code>Video_seek.Value = (</code><code>int</code><code>)(Framesno);</code>

<code>          </code><code>double</code> <code>time_index = _capture.GetCaptureProperty(Emgu.CV.CvEnum.CAP_PROP.CV_CAP_PROP_POS_MSEC);</code>

<code>          </code><code>Time_Label.Text = </code><code>"Time: "</code> <code>+ TimeSpan.FromMilliseconds(time_index).ToString().Substring(0, 8);</code>

<code>          </code><code>double</code> <code>framenumber = _capture.GetCaptureProperty(Emgu.CV.CvEnum.CAP_PROP.CV_CAP_PROP_POS_FRAMES);</code>

<code>          </code><code>Frame_lbl.Text = </code><code>"Frame: "</code> <code>+ framenumber.ToString();</code>

<code>          </code><code>Thread.Sleep((</code><code>int</code><code>)(1000.0 / FrameRate));</code>

<code>        </code><code>}</code>

<code>        </code><code>if</code> <code>(cam == 1)</code>

<code>          </code><code>Frame_lbl.Text = </code><code>"Frame: "</code> <code>+ (webcam_frm_cnt++).ToString();</code>

<code>   </code><code>catch</code> <code>(Exception ex)</code>

<code>     </code><code>MessageBox.Show(ex.Message.ToString());</code>

<code>}</code>

這個方法用來釋放資料. 它同時也釋放了捕獲變量所需要的一些資源.

<code>private</code> <code>void</code> <code>ReleaseData()</code>

<code>  </code><code>if</code> <code>(_capture != </code><code>null</code><code>)</code>

<code>        </code><code>_capture.Dispose();</code>

繼續閱讀