6

我正在使用实时 OCR 开发 Android 应用程序。我使用 OpenCV 和 Tesseract 库。但性能很差,即使在我的 Galaxy SIII 上也是如此。有什么方法可以提高性能?这是我的代码:

    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 API 会降低 tesseract OCR 的速度吗?在传递给 Tesseract API 之前,我应该执行哪些预处理?

4

4 回答 4

2

要尝试的一件事是使用自适应阈值(OpenCV 中的adaptiveThreshold)对图像进行二值化。

于 2013-04-21T08:57:35.850 回答
1

您可以让 Tesseract 只执行识别通道 1,以便在调用recog_all_words()时跳过通道 2 到 9 。

更改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)) {
于 2012-10-04T17:45:13.880 回答
0

一些可能使它更快的事情是:

  • 在 createBitmap 之前,从 mGray 中选择文本所在的较小区域 - 因此后续更重的方法会处理较小的图像。
  • 将 Bitmap.Config.ARGB_8888 更改为 Bitmap.Config.RGB_565 - 您的图像是灰度的,它不需要 ARGB 位图。
于 2012-10-04T09:00:06.533 回答
0

使用多线程,但请注意为 TessBaseAPI 每个线程创建一个实例。不要在不同的线程之间共享它们。创建 N 个线程(N >= 核心数),java 将确保您至少加速核心数倍。

我所做的是创建 N 个线程,它们在自己的上下文中(在 run 方法中)创建 TessBaseAPI 对象,并在循环中等待 OCR 请求直到被中断。

    ...
    ...
    @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 方法的本地对象,因此绝对不共享。

于 2017-01-19T11:20:37.740 回答