2016-11-21 71 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,則一秒的處理速度很慢。你需要讓事情變得更快,否則你將不得不建立一個巨大的緩衝區,並且希望如果它在路上忙碌,你將永遠趕上。

確保正確使用多個內核(如果可用),但最終知道哪些圖片不相關是提高性能的關鍵。