2011-09-22 33 views
1

使用Emgu.CV在這一點上我有一個要求從我的相機界面圖像的功能。然後將該圖像保存到硬盤,並顯示在Windows窗體GUI中。System.TypeInitializationException在C#

返回圖像的攝像頭界面內的功能如下: 高度和寬度都是攝像頭接口類的一部分的整數。在這種情況下,它們被設置爲800x600。

public Image<Bgr,byte> QueryFrame() 
{ 
    Image<Bgr, byte> temp; 
    lock (key) 
    { 
     using (Capture cap = new Capture()) 
     { 
      cap.SetCaptureProperty(Emgu.CV.CvEnum.CAP_PROP.CV_CAP_PROP_FRAME_HEIGHT, height); 
      cap.SetCaptureProperty(Emgu.CV.CvEnum.CAP_PROP.CV_CAP_PROP_FRAME_WIDTH, width); 
      temp = cap.QueryFrame().Copy(); 
     } 
    } 
    return temp; 
} 

調用該函數多次顯示首先捕獲一個幀需要相當長的時間,將程序鎖定幾秒鐘後停止使用。然後,在調試使用Visual C#2010程序運行時可捕獲幾幀後,Windows錯誤彈出的vshost.exe:

Faulting application DashboardGUI.vshost.exe, version 10.0.30319.1, time stamp 0x4ba2084b, faulting module MSVCR90.dll, version 9.0.30729.6161, time stamp 0x4dace5b9, exception code 0xc0000005, fault offset 0x00024682, process id 0xe78, application start time 0x01cc792086025f01. 

我隨後開始發佈應用程序,並從可執行文件運行,並得到錯誤:

Application: DashboardGUI.exe 
Framework Version: v4.0.30319 
Description: The process was terminated due to an unhandled exception. 
Exception Info: System.TypeInitializationException 
Stack: 
    at Emgu.CV.CvInvoke.cvReleaseCapture(IntPtr ByRef) 
    at Emgu.CV.Capture.DisposeObject() 
    at Emgu.Util.DisposableObject.Finalize() 

不過,我也有過它拋出與Emgu.CV.CvInvoke.cvCreateCameraCapture(Int32)將相同的異常。

是什麼原因造成了這些問題?他們怎樣才能避免?有沒有什麼辦法可以比現在更快地捕捉幀(當它不會崩潰)?

回答

3

我看了你的代碼,我看到的問題。我期望的崩潰原因是由於使用聲明,我建議對不起:s。那麼不完全是使用聲明。您似乎會經常訪問代碼以供系統處理。

Capture cap = new Capture() 

對少量代碼進行大量操作。它不僅與您的相機建立通信,而且還檢查它是否存在,處理驅動程序並創建環形緩衝區等。現在,雖然所提供的代碼確保只返回更新的圖像,但通常只有在您使用按鈕或定時器一段時間的延遲。現在,當我意識到你想要實現的目標時,並且由於你想要的圖像比通過這種方法合理實現的圖像更有規律,所以您有更實際的選擇。

全局配置您的捕獲設備並設置記錄,並呼籲ProcessFrame從緩衝區時,它可以得到一個圖像。現在只需更改您的QueryFrame即可複製剛獲得的任何幀。這將有希望阻止您獲得前一幀的問題,並且您現在將擁有最新的緩衝區。

private Capture cap; 
Image<Bgr, Byte> frame; 

public CameraCapture() 
{ 
    InitializeComponent(); 
    cap= new Capture(); 
    cap.SetCaptureProperty(Emgu.CV.CvEnum.CAP_PROP.CV_CAP_PROP_FRAME_HEIGHT, height); 
    cap.SetCaptureProperty(Emgu.CV.CvEnum.CAP_PROP.CV_CAP_PROP_FRAME_WIDTH, width); 

    Application.Idle += ProcessFrame; 
} 

private void ProcessFrame(object sender, EventArgs arg) 
{ 
    frame = _capture.QueryFrame(); 
    grayFrame = frame.Convert<Gray, Byte>(); 
} 

public Image<Bgr,byte> QueryFrame() 
{ 
    return frame.Copy(); 
} 

希望這有助於讓你的解決方案這個時候, 和遺憾,另一種方法是沒有用的,

乾杯 克里斯

+0

是啊,我想這會爲我需要它的工作!快速檢索幀,同時還能返回最新的圖像。將很快實施。再次感謝克里斯! – DArren

+0

它完美捕捉最新的幀,謝謝!我假設在1600x1200下運行時系統滯後不能停止(我有時想要以該分辨率捕捉幀)? – DArren

+0

不幸的是,除非你超頻你的處理器,並使用昂貴的快速低誤差RAM。我可以幫助加快任何分析,儘管取決於你做什麼>網絡並行工具箱可以加速你可能使用的任何For或Foreach循環,並且如果你有時間很容易實現看看http://msdn.microsoft.com /en-us/library/dd460693.aspx很高興它爲你工作:)乾杯 – Chris

相關問題