2016-11-21 3 views
0

OCR을 사용하여 C# WPF 자동 번호판 인식 기능을 개발 중입니다.비디오 스트림을 처리하는 동안 CPU 오버 헤드를 줄입니다.

흐름은입니다. 비디오 스트림 MJPEG에서 사진을 가져 오는 중입니다.이 이미지는 플레이트 번호 및 기타 세부 정보를 얻기 위해 OCR에 전달되어야합니다.

문제는입니다. 비디오 스트림은 초당 약 30 프레임을 생성하며 CPU는이 많은 처리를 처리 할 수 ​​없으며 또한 1 프레임을 처리하는 데 약 1 초가 소요됩니다. 또한 많은 프레임을 얻을 때 Queue에서 CPU는 70 % 사용됩니다 (Intel I7 4th G).

누구나 솔루션을 제안하고 더 나은 구현을 할 수 있습니까?

//This is the queue where it will hold the frames 
     // produced from the video streaming(video_Newfram1) 

     private readonly Queue<byte[]> _anpr1Produces = new Queue<byte[]>(); 


     //I am using AForg.Video to read the MJPEG Streaming 
     //this event will be triggered for every frame 
     private void video_NewFrame1(object sender, NewFrameEventArgs eventArgs) 
     { 

      var frameDataAnpr = new Bitmap(eventArgs.Frame); 
      AnprCam1.Source = GetBitmapimage(frameDataAnpr); 

      //add current fram to the queue 
      _anpr1Produces.Enqueue(imgByteAnpr); 

      //this worker is the consumer that will 
      //take the frames from the queue to the OCR processing 
      if (!_workerAnpr1.IsBusy) 
      { 
       _workerAnpr1.RunWorkerAsync(imgByteAnpr); 
      } 
     } 

     //This is the consumer, it will take the frames from the queue to the OCR 

     private void WorkerAnpr1_DoWork(object sender, DoWorkEventArgs e) 
     { 
      while (true) 
      { 
       if (_anpr1Produces.Count <= 0) continue; 
       BgWorker1(_anpr1Produces.Dequeue()); 
      } 
     } 

     //This method will process the frames that sent from the consumer 
     private void BgWorker1(byte[] imageByteAnpr) 
     { 
      var anpr = new cmAnpr("default"); 
      var objgxImage = new gxImage("default"); 

      if (imageByteAnpr != null) 
      { 
       objgxImage.LoadFromMem(imageByteAnpr, 1); 
       if (anpr.FindFirst(objgxImage) && anpr.GetConfidence() >= Configs.ConfidanceLevel) 
       { 
        var vehicleNumber = anpr.GetText(); 
        var vehicleType = anpr.GetType().ToString(); 
        if (vehicleType == "0") return; 

        var imagename = string.Format("{0:yyyy_MMM_dd_HHmmssfff}", currentDateTime) + "-1-" + 
            vehicleNumber + ".png"; 

        //this task will run async to do the rest of the process which is saving the vehicle image, getting vehicle color, storing to the database ... etc 
        var tsk = ProcessVehicle("1", vehicleType, vehicleNumber, imageByteAnpr, imagename, currentDateTime, anpr, _anpr1Produces); 

       } 
       else 
       { 
        GC.Collect(); 
       } 
      } 
     } 

답변

0

은 당신이해야 할 것은 이것이다 : 프레임이 가치가 처리인지 아닌지

먼저, 알아. 압축 된 비디오 스트림을 사용하는 경우 일반적으로 프레임의 압축 된 크기를 빠르게 읽을 수 있습니다. 현재 프레임과 이전 프레임 간의 차이를 저장합니다.

작지만 변화가 크지 않습니다 (차가 몰지 않는 경우).

프레임을 디코딩하지 않아도 모션 감지를 수행 할 수있는 최첨단 기술이며 매우 빨라야합니다.

그런 식으로 2 밀리 초 내에 프레임의 80 %를 건너 뛸 수 있습니다.

처리가 필요한 프레임을 한 번만 가져 오면됩니다. 느린 처리를하는 동안 녹음을 유지할 수 있도록 충분한 프레임을 버퍼링 할 수 있는지 확인하십시오.

다음으로해야 할 일은 관심 지역을 찾아 처음에 초점을 맞추는 것입니다. 색상이 변경된 부분을 보거나 사각형 모양을 찾으려고하면됩니다.

30fps를 처리해야하는 경우 마지막으로 1 초의 처리가 느립니다. 일을 더 빨리해야하거나 거대한 완충 장치를 만들어야하고 길에서 바쁘다면 따라 잡을 수 있기를 바랍니다.

여러 코어를 사용할 수 있다면 적절하게 사용하십시오. 그러나 결국 이미지의 어떤 부분이 적합하지 않은지 아는 것이 빠른 성능의 핵심입니다.