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.
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;
}
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()
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)?
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.
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,
Cheers Chris
http://www.emgu.com/wiki/index.php/Setting_up_EMGU_C_Sharp - this really helped me when I was stuck on the same issue, it might be worth a look.
精彩评论