2012-10-03 52 views
5

我正在使用實時OCR處理Android應用程序。我使用OpenCV和Tesseract Library。但是,即使在我的Galaxy SIII上,表現也很差。有什麼方法可以提高性能?這是我的代碼:通過Android上的OpenCV提高Tesseract性能

Mat mGray = new Mat(); 
capture.retrieve(mGray); 
Bitmap bmp = Bitmap.createBitmap(mGray.cols(), mGray.rows(), Bitmap.Config.ARGB_8888); 
tessBaseApi.setImage(bmp); 
String recognizedText = tessBaseApi.getUTF8Text(); 
Log.i("Reg", recognizedText); 

Tesseract OCR的速度是否會通過傳遞位圖到Tesseract API來降低速度?我應該在傳遞給Tesseract API之前執行哪些預處理?

+0

您是否在談論速度或識別的準確性? – rmtheis

+1

我正在考慮速度,這是非常緩慢的。 –

+0

嘿@QuiLlHoN你有沒有發現任何解決方案如此緩慢的表現?我遇到了同樣的問題:/ – Vucko

回答

0

有些事情可能使它更快是:

  • 選擇從mGray一個較小的區域,其中的文字,createBitmap前 - 讓後續處理較小的圖像更重的方法。
  • 將Bitmap.Config.ARGB_8888更改爲Bitmap.Config.RGB_565 - 您的圖像是灰度,它不需要ARGB位圖。
+0

TessBaseAPI只接受ARGB_8888圖像。有找到文本區域的任何算法?謝謝。 –

1

你可以有正方體只能做識別合格1,使其跳過經過2至9, 當它調用recog_all_words()

變化baseapi.cpp 以下行和重建的Tesseract庫項目:

if (tesseract_->recog_all_words(page_res_, monitor, NULL, NULL, 0)) { 

將其更改爲:

if (tesseract_->recog_all_words(page_res_, monitor, NULL, NULL, 1)) { 
+0

我編輯了代碼並重建了庫。但速度還是很慢的。 –

2

一件事是嘗試以二進制化利用自適應閾值圖像(adaptiveThreshold在OpenCV中)。

+1

Tesseract已經在內部執行此操作。它使用Otsu的Thresholding。 https://code.google.com/p/tesseract-ocr/source/browse/ccstruct/otsuthr.cpp – Raghav

+0

大津的方法使用單個全局閾值。如果照明是不完全均勻的(參見http://docs.opencv.org/trunk/doc/py_tutorials/py_imgproc/py_thresholding/py_thresholding.html#adaptive-thresholding的例子) – ojs

+0

實際上這並不作爲自適應閾值工作,以及大津不是很好,但它仍然非常快。所以雖然這可能解決精度問題,但它不會大大影響性能。 –

0

使用多線程,但要注意爲TessBaseAPI的每個線程創建一個實例。不要在不同的線程之間分享它們。創建N個線程(N> =內核數量),java將確保至少加快內核次數。

我要做的就是創造它在自己的環境中創建TessBaseAPI對象(run方法),並等待在一個循環OCR請求,直至打斷了N個線程。

... 
    ... 
    @Override 
    public void run() { 

     TessBaseAPI tessBaseApi = new TessBaseAPI(); 

     tessBaseApi.init(Ocrrrer.DATA_PATH, "eng"); 

     setTessVariable(tessBaseApi, "load_system_dawg", "0"); 
     setTessVariable(tessBaseApi, "load_freq_dawg", "0"); 
     setTessVariable(tessBaseApi, "load_unambig_dawg", "0"); 
     setTessVariable(tessBaseApi, "load_punc_dawg", "0"); 
     setTessVariable(tessBaseApi, "load_number_dawg", "0"); 
     setTessVariable(tessBaseApi, "load_fixed_length_dawgs", "0"); 
     setTessVariable(tessBaseApi, "load_bigram_dawg", "0"); 
     setTessVariable(tessBaseApi, "wordrec_enable_assoc", "0"); 
     setTessVariable(tessBaseApi, "tessedit_enable_bigram_correction", "0"); 
     setTessVariable(tessBaseApi, "assume_fixed_pitch_char_segment", "1"); 
     setTessVariable(tessBaseApi, TessBaseAPI.VAR_CHAR_WHITELIST, "1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ<"); 

     Log.d(TAG, "Training file loaded"); 


     while (!interrupted()) { 
     reentrantLock.lock(); 
     try { 
      Log.d(TAG, this.getName() + " wait for OCR"); 
      jobToDo.await(); 
      Log.d(TAG, this.getName() + " input arrived. Do OCR"); 
      this.ocrResult = doOcr(tessBaseApi); 
      ocrDone.signalAll(); 
     } catch (InterruptedException e) { 
      return; 
     } finally { 
      try { 
      reentrantLock.unlock(); 
      } catch (Exception ex) { 
      } 
     } 
     } 

    } 
    ... 
    ... 

您可以看到tessBaseApi對象是run方法的本地對象,因此絕對不會共享。