Emgu AccessViolationException occurs randomly after upgrading from Emgu 2 to Emgu 3.1.0.1
I used Emgu 2 (the one that was using opencv 2.4.10.1) and it ran pretty stable and ran smoothly. I am now upgrading to Emgu 3.1.0.1 and my application will sometimes crash for hours or a day with an AccessViolationException. I saw it crash in two different places. See the two locations marked in the source code below (CRASH1 and CRASH2). So I think there is something fundamentally wrong here.
I am running version of software version. Anyone got any ideas on what might be going on here?
The exception for CRASH1 is:
Framework Version: v4.0.30319
Description: The process was terminated due to an unhandled exception.
Exception Info: System.AccessViolationException
at Emgu.CV.CvInvoke.cveSubtract(IntPtr, IntPtr, IntPtr, IntPtr, Emgu.CV.CvEnum.DepthType)
at Emgu.CV.CvInvoke.Subtract(Emgu.CV.IInputArray, Emgu.CV.IInputArray, Emgu.CV.IOutputArray, Emgu.CV.IInputArray, Emgu.CV.CvEnum.DepthType)
at Emgu.CV.RotationMatrix2D.CreateRotationMatrix(System.Drawing.PointF, Double, System.Drawing.Size, System.Drawing.Size ByRef)
at Emgu.CV.Image`2[[Emgu.CV.Structure.Bgr, Emgu.CV.World, Version=3.1.0.2282, Culture=neutral, PublicKeyToken=7281126722ab4438],[System.Byte, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]].Rotate(Double, System.Drawing.PointF, Emgu.CV.CvEnum.Inter, Emgu.CV.Structure.Bgr, Boolean)
at Emgu.CV.Image`2[[Emgu.CV.Structure.Bgr, Emgu.CV.World, Version=3.1.0.2282, Culture=neutral, PublicKeyToken=7281126722ab4438],[System.Byte, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]].Rotate(Double, Emgu.CV.Structure.Bgr, Boolean)
at XXXX.ProcessFrames()
at System.Threading.ExecutionContext.RunInternal(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object, Boolean)
at System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object, Boolean)
at System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object)
at System.Threading.ThreadHelper.ThreadStart()
The CRASH2 exception is:
Framework Version: v4.0.30319
Description: The process was terminated due to an unhandled exception.
Exception Info: System.AccessViolationException
at Emgu.CV.Util.VectorOfMat.VectorOfMatPush(IntPtr, IntPtr)
at Emgu.CV.Util.VectorOfMat..ctor(Emgu.CV.Mat[])
at XXXX.ProcessFrames()
at System.Threading.ExecutionContext.RunInternal(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object, Boolean)
at System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object, Boolean)
at System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object)
at System.Threading.ThreadHelper.ThreadStart()
Source:
public void start()
{
started = true;
// start processing camera frames
cameraThread = new Thread(new ThreadStart(ProcessFrames));
cameraThread.IsBackground = true;
cameraThread.Start();
}
private void ProcessFrames()
{
Bgr frameBg = new Bgr(0,0,0);
while (true)
{
// try to open the camera device
if (capture == null)
{
try
{
int index;
bool isNumeric = int.TryParse(ConfigurationManager.AppSettings["CameraSource"], out index);
capture = isNumeric ? new Capture(index) : new Capture(ConfigurationManager.AppSettings["CameraSource"]);
capture.SetCaptureProperty(Emgu.CV.CvEnum.CapProp.FrameWidth, 640);
capture.SetCaptureProperty(Emgu.CV.CvEnum.CapProp.FrameHeight, 480);
capture.SetCaptureProperty(Emgu.CV.CvEnum.CapProp.FourCC, Emgu.CV.VideoWriter.Fourcc('M', 'J', 'P', 'G'));
}
catch
{
frameObservers.ForEach(a => a.frame(cameraNotConnectedBitmap, new List<Person>(), recognizer.isActive()));
}
Task.Delay(1000).Wait();
continue;
}
// read a frame from the camera
Mat matFrame = capture.QueryFrame();
Image<Bgr, byte> frame = null;
if (matFrame != null)
{
frame = matFrame.ToImage<Bgr, byte>();
}
if (frame == null)
{
frameObservers.ForEach(a => a.frame(cameraNotConnectedBitmap, new List<Person>(), recognizer.isActive()));
capture = null; // force to reconnect to camera again
Task.Delay(1000).Wait();
continue;
}
try
{
CRASH1 >>>frame = frame.Rotate(Convert.ToInt32(ConfigurationManager.AppSettings["CameraRotation"]), frameBg, false);
double scale = Convert.ToDouble(ConfigurationManager.AppSettings["CameraScale"]);
if (scale > 0)
{
frame = frame.Resize(scale, Emgu.CV.CvEnum.Inter.Linear);
}
Global.FRAME_HEIGHT = frame.Height;
Global.FRAME_WIDTH = frame.Width;
rawCameraFeedFrameObservers.ForEach(a => a.frame(frame));
if (autoBrightness)
{
Image<Lab, Byte> lab = frame.Convert<Lab, Byte>();
Image<Gray, Byte>[] planes = lab.Split();
CvInvoke.CLAHE(planes[0], claheClipLimit, new Size(8, 8), planes[0]);
CRASH2 >>>VectorOfMat vm = new VectorOfMat(planes[0].Mat, planes[1].Mat, planes[2].Mat);
CvInvoke.Merge(vm, lab);
frame = lab.Convert<Bgr, Byte>();
}
}
catch
{
// not the end of the world
Log.INFO("INFO", "Processing the frame failed, skipping this frame");
continue;
}
}
}
source to share
Perhaps one thread will access the system device and initialization is done by another parallel thread ...
As both Crash1 and Crash2 exceptions show this line
at System.Threading.ThreadHelper.ThreadStart()
Have you tried catching the exception directly on cameraThread.Start()
?
public void start()
{
started = true;
// start processing camera frames
cameraThread = new Thread(new ThreadStart(ProcessFrames));
cameraThread.IsBackground = true;
try
{
cameraThread.Start();
}
catch
{
started = false;
/* HERE ACCESS VIOLATION APPEAR, SO DELAY */
Task.Delay(1000).Wait();
/* AND RETRY */
}
continue;
}
source to share