在C#中使用Emgu.CV的System.TypeInitializationException

时间:2011-09-22 12:27:55

标签: c# computer-vision emgucv

此时我有一个功能,需要从我的相机界面调用图像。然后,此映像将保存到硬盘驱动器中,并显示在Windows窗体GUI中。

返回图像的相机界面内的功能如下: height和width都是整数,它们是相机接口类的一部分。在这种情况下,它们被设置为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在Debug中运行程序时捕获几帧后,为vshost.exe弹出了一个Windows错误:

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)抛出相同的异常。

造成这些问题的原因是什么?他们怎么能避免?是否有任何方法可以比现在更快地捕获帧(当它没有崩溃时)?

2 个答案:

答案 0 :(得分:3)

我看了你的代码,我看到了问题。我之所以崩溃的原因是由于我建议的使用声明抱歉:s。那不完全是使用声明。您似乎经常访问代码以供系统处理。

Capture cap = new Capture()

对少量代码执行大量操作。它不仅设置与您的相机的通信,但检查它是否存在,处理驱动程序并创建环形缓冲区等。现在,虽然给出的代码确保只返回更新的图像,但通常只有使用按钮或计时器时才能正常工作一段时间的延迟。现在,因为我知道你想要实现的目标,并且因为你想要使用这种方法可以合理地实现图像,所以你有一个更实用的选择。

全局设置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();
}

希望这次有助于您找到解决方案, 对不起,另一种方法没用,

干杯 克里斯

答案 1 :(得分:1)

http://www.emgu.com/wiki/index.php/Setting_up_EMGU_C_Sharp - 当我遇到同样的问题时,这确实对我很有帮助,可能值得一看。