2017-04-18 7 views
0

Android 용 Xamarin 및 OpenCV C# 바인딩 라이브러리를 사용하여 간단한 광학 측정 응용 프로그램을 작성하고 있습니다.BlockingCollections, Tasks 및 OpenCV로 시간이 지남에 따른 성능 저하

프레임 그래버를 처리에서 분리하기 위해 여러 스레드간에 원본 이미지를 처리 ​​한 다음 처리 된 이미지를 전달하는 블로킹 컬렉션을 만들었습니다. 나는 약 30 초 동안 GUI가 고르지 않은 비디오 (10 초)로 아름답게 매끄럽게 처리 된 비디오 (15 초)를 보여주고 충돌이 발생하는 문제가 있습니다.

아래 코드는 컬렉션의 정의를 보여줍니다. OnCameraFrame (코드의 맨 아래)은 각 새 프레임을 camframes 컬렉션으로 이동합니다. OnCreate에서 프레임을 가져 와서 많은 일을하고 그것을 외부 프레임 컬렉션에 채우는 CamProcessor라는 작업을 실행합니다. 그런 다음 OnCameraFrame은 처리 된 프레임을 GUI에 표시합니다. 이 게시물과 테스트를 위해 모든 처리 과정을 완전히 주석 처리 했으므로이 문제는 원시 데이터를 콜렉션을 통해 전달하는 것만으로 존재합니다.

다른 하나는 내 컬렉션이 매우 빠르게 실행되는 것입니다. 어떤 시점에서 나는 거기에 1 개 이상의 프레임을 가지고 있지 않으므로 오버 플로우 문제는 아닙니다 (제 생각에).

누구든지이 전략이 효과적이지 않은 이유를 지적 할 수 있습니까?

BlockingCollection<Mat> camframes = new BlockingCollection<Mat>(10); 
BlockingCollection<Mat> outframes = new BlockingCollection<Mat>(10); 
public CameraBridgeViewBase mOpenCvCameraView { get; private set; } 

    protected override void OnCreate(Bundle savedInstanceState) 
    { 
     //LayoutStuff 

     mOpenCvCameraView = FindViewById<CameraBridgeViewBase>(Resource.Id.squish_cam); 

     Task.Run(() => camProcessor()); 
    } 

    public void camProcessor() 
    { 
     while (!camframes.IsCompleted) 
     { 
      Mat frame = new Mat(); 
      try 
      { 
       frame = camframes.Take(); 
      } 
      catch (InvalidOperationException) { } 

      Mat frameT = frame.T(); 
      Core.Flip(frame.T(), frameT, 1); 
      Imgproc.Resize(frameT, frameT, frame.Size()); 
      outframes.Add(frameT); 
     } 
    } 

    public Mat OnCameraFrame(CameraBridgeViewBase.ICvCameraViewFrame inputFrame) 
    { 
     mRgba = inputFrame.Rgba(); 
     Mat frame = new Mat(); 
     Task.Run(() => camframes.Add(mRgba)); 
     try 
     { 
      frame = outframes.Take(); 
     } 
     catch (InvalidOperationException) { } 

     return frame; 
    } 

답변

0

Android SDK monitor.bat 결과를 살펴본 결과, 이것은 메모리 누수임을 알게되었습니다. Java OpenCV 래퍼에 공통적 인 것으로 밝혀졌으며 OpenCV의 매트 힙이 C#보다 많기 때문에 가비지 수집이되지 않습니다.

   GCSettings.LargeObjectHeapCompactionMode = GCLargeObjectHeapCompactionMode.CompactOnce; 
      GC.Collect(); 
      GC.WaitForPendingFinalizers(); 
:

용액을 매 프레임 잡아 이들를 추가했다