2012-10-03 11 views
5

Pracuję nad aplikacją na Androida za pomocą OCR w czasie rzeczywistym. Używam OpenCV i biblioteki Tesseract. Ale wydajność jest bardzo słaba, nawet na moim Galaxy SIII. Czy istnieją jakieś metody poprawy wydajności? To jest mój kodu:poprawić wydajność Tesseract z OpenCV na Androidzie

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); 

Czy prędkość Tesseract OCR być zmniejszone przez przepuszczenie bitmapę do API Tesseract? Jakie wstępne przetwarzanie należy wykonać przed przejściem do interfejsu API Tesseract?

+0

Czy mówisz o dokładności prędkości lub rozpoznawania? – rmtheis

+1

Podejmuję temat prędkości, jest bardzo wolny. –

+0

Hey @QuiLlHoN Czy znalazłeś jakieś rozwiązanie dla tak niskiej wydajności? Pojawia się ten sam problem:/ – Vucko

Odpowiedz

0

Niektóre rzeczy, które może zrobić to szybciej to:

  • Wybierz mniejszy region z mGray gdzie tekst jest przed createBitmap - tak bardziej ciężkich metod, które następują proces mniejszy obraz.
  • Zmiana Bitmap.Config.ARGB_8888 na Bitmap.Config.RGB_565 - obraz jest w skali szarości, nie będzie potrzebował bitmapy ARGB.
+0

TessBaseAPI akceptuje tylko obraz ARGB_8888. Czy istnieją jakieś algorytmy wyszukiwania regionu tekstowego? Dziękuję Ci. –

1

Można mieć tesseract tylko zrobić przepustkę rozpoznawania 1, tak, że pomija przechodzi od 2 do 9, gdy wywołuje recog_all_words().

Zmień następujący wiersz w baseapi.cpp i odbudować swój projekt biblioteki tesseract:

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

go zmienić na:

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

Edytowałem kod i przebudowałem bibliotekę. Ale prędkość nadal jest bardzo powolna. –

2

Jedno spróbować jest binarize obraz przy użyciu adaptacyjnego obcinanie (adaptiveThreshold w OpenCV).

+1

Tesseract już to wykonuje wewnętrznie. Używa Thresholdingu Otsu. https://code.google.com/p/tesseract-ocr/source/browse/ccctct/otsuthr.cpp – Raghav

+0

Metoda Otsu wykorzystuje jeden globalny próg. To nie działa jak również adaptacyjne Progowanie gdy oświetlenie nie jest całkowicie jednolity (patrz http://docs.opencv.org/trunk/doc/py_tutorials/py_imgproc/py_thresholding/py_thresholding.html#adaptive-thresholding przykłady) – ojs

+0

Rzeczywiście Otsu nie działa tak dobrze, ale wciąż jest bardzo szybki. Tak więc, chociaż może to rozwiązać problemy z precyzją, nie ma to większego wpływu na wydajność. –

0

Użyj wielowątkowości, ale pamiętaj, aby utworzyć jedną instancję na wątek dla TessBaseAPI. Nie udostępniaj ich między różnymi wątkami. Utwórz N wątków (N> = liczba rdzeni), a java zapewni przyspieszenie co najmniej liczby rdzeni.

To, co robię, to tworzenie wątków N, które tworzą obiekty TessBaseAPI w ich własnym kontekście (w metodzie run) i oczekiwanie na żądania OCR w pętli, aż do przerwania.

... 
    ... 
    @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) { 
      } 
     } 
     } 

    } 
    ... 
    ... 

Można zobaczyć, że obiekt tessBaseApi jest lokalny do sposobu wykonywania, dlatego absolutnie nie jest dzielona.

Powiązane problemy