2017-05-26 2 views
3

Emgu 2(opencv 2.4.10.1を使用していました)を使用していて、かなり安定して動作していて、クラッシュすることなく動作します。 Emgu 3.1.0.1にアップグレードしました。私のアプリは、時折、または1日以内にAccessViolationExceptionでクラッシュすることがあります。私は今、2つの異なる場所でそれがクラッシュするのを見ました。以下のソースコードにある2つの場所(CRASH1 & CRASH2)を参照してください。だから私は根本的に何かが間違っていると思う。Emgu 2からEmgu 3.1.0.1へのアップグレード後にEmgu AccessViolationExceptionがランダムに発生しました

私はソフトウェアのリリースバージョンを実行しています。誰もがここで何が起こっているかもしれない考えを持っていますか?

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

これは単に、以前のライブラリバージョン – slawekwin

+0

に現れなかったことを、あなたの問題は別の場所で可能性があり、おそらくレース状態や管理対象外のデータの他の取扱いミスのいくつかの種類に関係して、より大きなアプリケーションの一つのスレッドのように見えますスレッドは基本的にカメラからフレームを取得し、コード内に見られるように処理し、それをUIスレッドにポストします。これにより、フレームのビットマップが作成され、画面に表示されます。とにかくUIスレッドのコードはフレームを操作しません。だから私はそれがアクセス違反を作成する方法を見ることができません。 – rukiman

+0

EMGUの試行でアクセス違反の問題があった場合(特にBOW関連の呼び出しでは)、すべてのディスポーザブル(つまりMat)を処分することをお勧めします。私はOpenCVSharpを使い始めました。しかし最新のバージョンには、私が使っているいくつかのseriosの問題があります:https://www.nuget.org/packages/OpenCvSharp3-AnyCPU/3.2.0.20170324 – Koray

答えて

0

多分1つのスレッドが初期化中に、システムのデバイスにアクセスします別の並列スレッドによって行われます...

両方CRASH1 & 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; 
} 
関連する問題