2012-10-03 53 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方法的本地对象,因此绝对不会共享。