使用Tesseract的Android OCR应用程序

insrf1ej  于 2023-03-11  发布在  Android
关注(0)|答案(3)|浏览(132)

我是按照这个网站上提到的教程:
http://gaut.am/making-an-ocr-android-app-using-tesseract/
首先,我从github导入了Tess-Twohttps://github.com/rmtheis/tess-two
并将其链接到我的项目https://github.com/GautamGupta/Simple-Android-OCR
应用程序编译和运行都很好。但是当我点击一张图片后,当我点击保存它崩溃了。
以下是源主要活动:

public class SimpleAndroidOCRActivity extends Activity {
  public static final String PACKAGE_NAME = "com.datumdroid.android.ocr.simple";
  public static final String DATA_PATH = Environment
                    .getExternalStorageDirectory().toString() + "/SimpleAndroidOCR/";

  // You should have the trained data file in assets folder
  // You can get them at:
  // http://code.google.com/p/tesseract-ocr/downloads/list
  public static final String lang = "eng";

  private static final String TAG = "SimpleAndroidOCR.java";

  protected Button _button;
  // protected ImageView _image;
  protected EditText _field;
  protected String _path;
  protected boolean _taken;

  protected static final String PHOTO_TAKEN = "photo_taken";

  @Override
  public void onCreate(Bundle savedInstanceState) {

    String[] paths = new String[] { DATA_PATH, DATA_PATH + "tessdata/" };

    for (String path : paths) {
      File dir = new File(path);
      if (!dir.exists()) {
        if (!dir.mkdirs()) {
          Log.v(TAG, "ERROR: Creation of directory " + path + " on sdcard failed");
          return;
        } else {
          Log.v(TAG, "Created directory " + path + " on sdcard");
        }
      }
    }

    // lang.traineddata file with the app (in assets folder)
    // You can get them at:
    // http://code.google.com/p/tesseract-ocr/downloads/list
    // This area needs work and optimization
    if (!(new File(DATA_PATH + "tessdata/" + lang + ".traineddata")).exists()) {
      try {
        AssetManager assetManager = getAssets();
        InputStream in = assetManager.open("tessdata/" + lang + ".traineddata");
        //GZIPInputStream gin = new GZIPInputStream(in);
        OutputStream out = new FileOutputStream(DATA_PATH
                                            + "tessdata/" + lang + ".traineddata");

        // Transfer bytes from in to out
        byte[] buf = new byte[1024];
        int len;
        //while ((lenf = gin.read(buff)) > 0) {
        while ((len = in.read(buf)) > 0) {
          out.write(buf, 0, len);
        }
        in.close();
        //gin.close();
        out.close();

        Log.v(TAG, "Copied " + lang + " traineddata");
      } catch (IOException e) {
        Log.e(TAG, "Was unable to copy " + lang + " traineddata " + e.toString());
      }
    }

    super.onCreate(savedInstanceState);

    setContentView(R.layout.main);

    // _image = (ImageView) findViewById(R.id.image);
    _field = (EditText) findViewById(R.id.field);
    _button = (Button) findViewById(R.id.button);
    _button.setOnClickListener(new ButtonClickHandler());

    _path = DATA_PATH + "/ocr.jpg";
  }

  public class ButtonClickHandler implements View.OnClickListener {
    public void onClick(View view) {
      Log.v(TAG, "Starting Camera app");
        startCameraActivity();
      }
    }

  // Simple android photo capture:
  // http://labs.makemachine.net/2010/03/simple-android-photo-capture/

  protected void startCameraActivity() {
    File file = new File(_path);
    Uri outputFileUri = Uri.fromFile(file);

    final Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
    intent.putExtra(MediaStore.EXTRA_OUTPUT, outputFileUri);

    startActivityForResult(intent, 0);
  }

  @Override
  protected void onActivityResult(int requestCode, int resultCode, Intent data) {

    Log.i(TAG, "resultCode: " + resultCode);

    if (resultCode == -1) {
      onPhotoTaken();
    } else {
      Log.v(TAG, "User cancelled");
    }
  }

  @Override
  protected void onSaveInstanceState(Bundle outState) {
    outState.putBoolean(SimpleAndroidOCRActivity.PHOTO_TAKEN, _taken);
  }

  @Override
  protected void onRestoreInstanceState(Bundle savedInstanceState) {
    Log.i(TAG, "onRestoreInstanceState()");
    if (savedInstanceState.getBoolean(SimpleAndroidOCRActivity.PHOTO_TAKEN)) {
      onPhotoTaken();
    }
  }

  protected void onPhotoTaken() {
    _taken = true;

    BitmapFactory.Options options = new BitmapFactory.Options();
    options.inSampleSize = 4;

    Bitmap bitmap = BitmapFactory.decodeFile(_path, options);

    try {
      ExifInterface exif = new ExifInterface(_path);
      int exifOrientation = exif.getAttributeInt(
                                    ExifInterface.TAG_ORIENTATION,
                                    ExifInterface.ORIENTATION_NORMAL);

      Log.v(TAG, "Orient: " + exifOrientation);

      int rotate = 0;

      switch (exifOrientation) {
        case ExifInterface.ORIENTATION_ROTATE_90:
          rotate = 90;
          break;
        case ExifInterface.ORIENTATION_ROTATE_180:
          rotate = 180;
          break;
        case ExifInterface.ORIENTATION_ROTATE_270:
          rotate = 270;
          break;
      }

      Log.v(TAG, "Rotation: " + rotate);

      if (rotate != 0) {

        // Getting width & height of the given image.
        int w = bitmap.getWidth();
        int h = bitmap.getHeight();

        // Setting pre rotate
        Matrix mtx = new Matrix();
        mtx.preRotate(rotate);

        // Rotating Bitmap
        bitmap = Bitmap.createBitmap(bitmap, 0, 0, w, h, mtx, false);
      }

      // Convert to ARGB_8888, required by tess
      bitmap = bitmap.copy(Bitmap.Config.ARGB_8888, true);

    } catch (IOException e) {
      Log.e(TAG, "Couldn't correct orientation: " + e.toString());
    }

    // _image.setImageBitmap( bitmap );

    Log.v(TAG, "Before baseApi");

    TessBaseAPI baseApi = new TessBaseAPI();
    baseApi.setDebug(true);
    baseApi.init(DATA_PATH, lang);
    baseApi.setImage(bitmap);

    String recognizedText = baseApi.getUTF8Text();

    baseApi.end();

    // You now have the text in recognizedText var, you can do anything with it.
    // We will display a stripped out trimmed alpha-numeric version of it (if lang is eng)
    // so that garbage doesn't make it to the display.

    Log.v(TAG, "OCRED TEXT: " + recognizedText);

    if ( lang.equalsIgnoreCase("eng") ) {
        recognizedText = recognizedText.replaceAll("[^a-zA-Z0-9]+", " ");
    }

    recognizedText = recognizedText.trim();

    if ( recognizedText.length() != 0 ) {
      _field.setText(_field.getText().toString().length() == 0 ? recognizedText : _field.getText() + " " + recognizedText);
      _field.setSelection(_field.getText().toString().length());
    }     
    // Cycle done.
  }

  // www.Gaut.am was here
  // Thanks for reading!
}

而且我知道错误在下面的部分接近尾声:

TessBaseAPI baseApi = new TessBaseAPI();
baseApi.setDebug(true);
baseApi.init(DATA_PATH, lang);
baseApi.setImage(bitmap);

String recognizedText = baseApi.getUTF8Text();

baseApi.end();

你知道它为什么会坠毁吗?

igsr9ssn

igsr9ssn1#

去解压缩你的目标 *.apk文件,检查是否有一个libs文件夹中包含 *.so文件。如果这是你的问题,检查这个链接,我已经回答过了。

zzlelutf

zzlelutf2#

您使用的是正确的tessdata文件吗?如果不是,请访问https://github.com/tesseract-ocr/tesseract/wiki/Data-Files#data-files-for-version-304305

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

将文件保存到目录时可能存在权限问题。
或者检查代码目录的lib文件夹,可能是libtess.so文件不适用于x86、x64、mips、armv7等CPU架构的问题。

anhgbhbe

anhgbhbe3#

问题出在您的路径上,您必须下载一种语言,以便从code.google.com/p/tesseract-ocr/downloads/list download获得结果(例如:tesseract-ocr-3.02.eng.tar.gz)将其解压缩并找到文件“yourLanguage.traineddata”(例如:“eng.traineddata”),并把这个文件在你的存储路径在sd卡,然后你可以得到它作为一个路径

TessBaseAPI mTess = new TessBaseAPI();
String datapath = Environment.getExternalStorageDirectory() + "/tesseract/";
String language = "eng";
File dir = new File(datapath + "tessdata/");
if (!dir.exists())
    dir.mkdirs();
mTess.init(datapath, language);
mTess.setImage(yourBitmapImage);
String result = mTess.getUTF8Text();
Toast.makeText(tesswork.this, "Result : " + result, Toast.LENGTH_LONG).show();

相关问题