2016-11-21 34 views
0

我正在开发使用OCR进行C#WPF自动车牌识别。在处理视频流时减少CPU开销

该流程是,我从视频流MJPEG中获取图片,并且应将此图片传递到OCR以获取版号和其他详细信息。

问题是:视频流产生大约30帧/秒,CPU不能处理这么多的处理也需要大约1秒处理1帧,另外当我会得到很多帧在队列上,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

你应该做的是这样的:

首先,计算出,如果一个框架是值得的处理与否。如果您使用的是压缩视频流,通常可以快速读取帧的压缩大小。它存储当前帧和前一帧之间的差异。

当它很小,没有太大的变化(即:没有车开过)。

这是一种低技术的运动检测方式,甚至不需要解码帧,它应该是非常快的。

这样,您可以决定在几毫秒内跳过80%的帧。

有一次,你会得到需要处理的帧。确保您可以缓冲足够的帧,以便在进行缓慢处理时保持录制。

接下来要做的是找到一个感兴趣的区域,并首先关注那些区域。您可以通过简单地查看颜色更改的区域或尝试查找矩形形状来实现此目的。

最后,如果您需要处理30 fps,则一秒的处理速度很慢。你需要让事情变得更快,否则你将不得不建立一个巨大的缓冲区,并且希望如果它在路上忙碌,你将永远赶上。

确保正确使用多个内核(如果可用),但最终知道哪些图片不相关是提高性能的关键。