从Emgu 2升级到Emgu 3.1.0.1后随机发生的Emgu AccessViolationException

时间:2017-05-26 03:49:34

标签: c# opencv emgucv

我正在使用Emgu 2(使用opencv 2.4.10.1的那个)并且运行非常稳定并且可以在不崩溃的情况下运行。我现在已升级到Emgu 3.1.0.1,我的应用程序有时会在几小时或一天内因AccessViolationException而崩溃。我现在看到它在两个不同的位置崩溃了。请参阅下面源代码中标记的两个位置(CRASH1和CRASH2)。所以我认为这里有一些根本性的错误。

我正在运行该软件的发行版。任何人都有任何想法可能会发生在这里?

CRASH1例外是:

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

CRASH2例外是:

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

源代码是:

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

1 个答案:

答案 0 :(得分:0)

当初始化由另一个并发线程完成时,也许一个线程将访问系统设备......

同时Crash1&amp; Crash2异常显示此行

at System.Threading.ThreadHelper.ThreadStart()

您是否尝试直接在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;
}