无法使用语言=eng初始化Tesseract API

7
我正在开发一个需要OCR的Android应用。我决定使用Tesseract作为API,但是一直出现以下错误信息:
E/Tesseract(native): Could not initialize Tesseract API with language=eng!
以下是我的解决方案:
1. 已经将文件 "eng.traineddata" 复制到指定位置。 2. 使用 Android Studio 2.1.2 (SDK 23)。 3. 在运行Android Lollipop 5.1.1 的API 22设备上进行测试(了解Marshmallow权限问题)。
以下是我使用的代码:
public void reads(View view) {

  TextView textView = (TextView) findViewById(R.id.textView);

  int rotation = 0;

  try {
    ExifInterface exifInterface = new ExifInterface(mCurrentPhotoPath);
    int orientation = exifInterface.getAttributeInt(ExifInterface.TAG_ORIENTATION,ExifInterface.ORIENTATION_NORMAL);

    switch (orientation){
      case ExifInterface.ORIENTATION_ROTATE_90: rotation = 90; break;
      case ExifInterface.ORIENTATION_ROTATE_180: rotation = 180; break;
      case ExifInterface.ORIENTATION_ROTATE_270: rotation = 270; break;
    }
  } catch(Exception e) {

  }

  int w = imageBitmap.getWidth();
  int h = imageBitmap.getHeight();

  if (rotation != 0) {
    Matrix matrix = new Matrix();
    matrix.preRotate(rotation);

    imageBitmap = Bitmap.createBitmap(imageBitmap,0,0,w,h,matrix,false);
  } else {
    imageBitmap = Bitmap.createBitmap(imageBitmap,0,0,w,h);
  }

  imageBitmap = imageBitmap.copy(Bitmap.Config.ARGB_8888,true);

  TessBaseAPI ReadIt = new TessBaseAPI();
  ReadIt.init("/storage/emulated/0/","eng");
  ReadIt.setImage(imageBitmap);

  String Text = ReadIt.getUTF8Text();

  if (Text!=null) textView.setText(Text);

}

我在我的build.gradle依赖中使用了这行代码:

compile 'com.rmtheis:tess-two:6.0.2'

此外,我通过下载到特定的目录中,将"eng.traineddata"拷贝到名为tessdata的文件夹中。


@rmtheis 请帮我解决这个问题。 - urpanjwani
你找到解决方案了吗? - Volodymyr Kulyk
7个回答

4
Tesseract-two没有使用最新版本的OCR引擎,而是使用了3.05版本,因此我们被迫使用这里的数据。看起来新数据使用了不同的模型,即神经网络。在4.0版本之前的旧模型工作方式有所不同。
我已尝试使用这里这里的数据集。这些数据集仅与最新版本的tesseract(4.0)兼容(来源),因此如果您使用较旧版本的tesseract,则无法正常工作。

你可以使用更新的lib,用法几乎相同,但是使用了tess 4。 - m'hd semps

3

请检查修改。我已经按照您说的做了。 - urpanjwani

3

在 Activity 中释放清单文件权限:

在清单文件中:

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>

在onCreate方法中:

    if (ContextCompat.checkSelfPermission(this,
            Manifest.permission.WRITE_EXTERNAL_STORAGE)
            != PackageManager.PERMISSION_GRANTED) {

        // Should we show an explanation?
        if (ActivityCompat.shouldShowRequestPermissionRationale(this,
                Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
        } else {
            ActivityCompat.requestPermissions(this,
                    new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},
                    1);
        }
    }

2
如果您没有使用Marshmallow并且仍然遇到问题,请尝试清理并重新构建项目。

1

我遇到了同样的问题,问题出在Marshmallow特别要求应用程序以新的方式获取对存储的读写权限。这篇博客文章解决了我的问题。

在我的主活动中我有以下代码:

@Override
protected void onCreate(Bundle savedInstanceState) {
    ...
    ...
    getStorageAccessPermissions(); // Request storage read/write permissions from the user
}

@TargetApi(23)
private void getStorageAccessPermissions() {
    int hasWriteStoragePermission = checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE);
    if (hasWriteStoragePermission != PackageManager.PERMISSION_GRANTED) {
        requestPermissions(new String[] {Manifest.permission.WRITE_EXTERNAL_STORAGE}, REQUEST_CODE_WRITE_EXTERNAL_PERMISSIONS);
    }
}

REQUEST_CODE_WRITE_EXTERNAL_PERMISSIONS是一个全局声明的整数常量。

在我扩展了TessBaseAPI的类中,我添加了以下内容,仅用于记录目的,以确保我实际上可以访问存储空间。

/* Checks if external storage is available to at least write to and returns the path name */
private static String isExternalStorageWritable() {
    String state = Environment.getExternalStorageState();
    String retval = "External storage is not writable";
    if (Environment.MEDIA_MOUNTED.equals(state)) {
        retval = Environment.getExternalStorageDirectory().toString();
    }
    return retval;
}

/* Checks if external storage is available to at least read from and returns the path name */
private static String isExternalStorageReadable() {
    String state = Environment.getExternalStorageState();
    String retval = "External storage is not readable";
    if (Environment.MEDIA_MOUNTED.equals(state) ||
            Environment.MEDIA_MOUNTED_READ_ONLY.equals(state)) {
        retval = Environment.getExternalStorageDirectory().toString();
    }
    return retval;
}

请注意,我没有在棉花糖上进行测试。 - urpanjwani

0
  • 使用外部存储器中的绝对路径来访问tessdata目录(而不是assets目录)
    例如,如果您的模型位于 /storage/emulated/0/Android/data/com.xxx.yyy/files/tessmodels/tessdata/ 请使用此路径 /storage/emulated/0/Android/data/com.xxx.yyy/files/tessmodels/
  • 确保您拥有读写外部存储器的权限
  • 使用this model,已经测试过可以与tess-two:9.0.0一起使用。我从tess-two示例应用程序中获取了它。

0
新版本的tess-two会检查训练数据文件是否可以在设备上找到。如果找不到这些训练数据文件,将显示比您看到的错误消息更详细的信息。
因此,当您在较新版本的tess-two上看到此错误消息时,这意味着训练数据文件已在预期位置找到,但它们是错误的版本或无法读取。请确保您正在使用正确版本的训练数据文件。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接