【问题标题】:System.TypeInitializationException using Emgu.CV in C#System.TypeInitializationException 在 C# 中使用 Emgu.CV
【发布时间】:2011-09-22 12:27:54
【问题描述】:

此时我有一个函数,它从我的相机界面调用图像。此图像随后会保存到硬盘驱动器并显示在 Windows 窗体 GUI 中。

相机接口内部返回图像的函数如下: 高度和宽度都是属于相机接口类的整数。在本例中,它们被设置为 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;
}

多次调用该函数首先表明捕获帧花费了相对较长的时间,从而将程序锁定了几秒钟而无法使用。然后,在 Debug with Visual C# 2010 中运行程序时捕获了几帧后,弹出 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) 抛出相同的异常。

是什么导致了这些问题?如何避免它们?有没有什么方法可以比现在更快地捕获帧(当它不崩溃时)?

【问题讨论】:

    标签: c# computer-vision emgucv


    【解决方案1】:

    我查看了您的代码,发现了问题。我期望它崩溃的原因是由于我建议的 using 语句抱歉:s。不完全是 using 语句。您似乎经常访问代码以供系统处理。

    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();
    }
    

    希望这次能帮助您找到解决方案, 抱歉,其他方法没用,

    干杯 克里斯

    【讨论】:

    • 啊,是的,我想这可以满足我的需要!快速检索帧,同时仍返回最新图像。将很快实施。再次感谢克里斯!
    • 完美捕捉最新帧,谢谢!我假设在 1600x1200 下运行时系统延迟无法停止(我有时想以该分辨率捕获帧)?
    • 不幸的是,并非如此,除非您对处理器进行超频并使用昂贵的快速低错误 RAM。我可以帮助加快任何分析,但取决于您所做的 >net 并行工具箱将加速您可能使用的任何 For 或 Foreach 循环,如果您有时间,它很容易实现看看msdn.microsoft.com/en-us/library/dd460693.aspx很高兴它对您有用结束 :) 干杯
    【解决方案2】:

    http://www.emgu.com/wiki/index.php/Setting_up_EMGU_C_Sharp - 当我被困在同一个问题上时,这真的帮助了我,它可能值得一看。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-09-14
      • 2017-10-07
      • 1970-01-01
      • 2020-12-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多