问题描述
此时我有一个函数,它从我的相机界面调用图像.此图像随后会保存到硬盘驱动器并显示在 Windows 窗体 GUI 中.
At this point I have a function which calls for an image from my camera interface. This image is then saved to hard drive and also displayed in the Windows Forms GUI.
相机接口内部返回图像的函数如下:高度和宽度都是属于相机接口类的整数.在本例中,它们被设置为 800x600.
The function inside the camera interface which returns the image is as follows: height and width are both integers that are part of the camera interface class. In this case they were set to 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 错误:
Calling the function a number of times revealed first that capturing a frame took a comparatively long time, locking the program out of use for a few seconds. Then, after capturing a few frames while running the program in Debug with Visual C# 2010, a windows error popped up for 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.
然后我继续发布应用程序并从可执行文件运行它并收到错误:
I then proceeded to publish the application and run it from the executable and got the error:
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) 抛出相同的异常.
However I have also had it throw the same exception with Emgu.CV.CvInvoke.cvCreateCameraCapture(Int32).
是什么导致了这些问题?如何避免它们?有没有什么方法可以比现在更快地捕获帧(当它不崩溃时)?
What is causing these problems? How can they be avoided? And is there any way to make capturing a frame faster than it currently does (when it doesn't crash)?
推荐答案
我看了你的代码,我发现了问题.我期望它崩溃的原因是由于我建议的 using 语句抱歉:s.不完全是 using 语句.您似乎经常访问代码以供系统处理.
I've looked at you code and I see the problem. The reason it crashes I expect is due to the using statement which I suggested Sorry :s. Well not exactly the using statement. You would appear to be accessing the code to often for the system to handle.
Capture cap = new Capture()
对少量代码执行大量操作.它不仅与您的相机建立通信,而且检查它是否存在,处理驱动程序并创建环形缓冲区等.现在,虽然给出的代码确实确保只返回更新的图像,但它通常只有在您使用按钮或计时器时才能正常工作一段时间的延迟.现在,由于我知道您尝试实现的目标,并且由于您想要的图像比使用此方法可以合理实现的图像更频繁,因此您有一个更实用的选择.
Does a large amount of operations for a small amount of code. Not only does it set up communication with your camera but checks it exists, handles drivers and creates ring buffers etc. Now while the code given does ensure only an updated image is returned it generally only works well if your using a button or a timer with a period of time delay. Now as I am aware of what your trying to achieve and since you want images more regularly than what can reasonably be achieved with this method you have a more practical option.
全局设置您的 Capture 设备并将其设置为记录并调用 ProcessFrame 以尽可能从缓冲区获取图像.现在更改您的 QueryFrame 以复制它刚刚获得的任何帧.这有望阻止您获取前一帧的问题,并且您现在将从缓冲区中获得最新的帧.
Set your Capture device up globally and set it of recording and calling ProcessFrame to get an image from the buffer whenever it can. Now change your QueryFrame simply to copy whatever frames its just acquired. This will hopefully stop your problem of getting the previous frame and you will now have the most recent frame out of the buffer.
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();
}
希望这次能帮助您找到解决方案,抱歉,其他方法没用,
Hope this helps get you to a solution this time, and sorry the other method was of no use,
干杯克里斯
这篇关于System.TypeInitializationException 在 C# 中使用 Emgu.CV的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持跟版网!