当前位置: 首页 > 知识库问答 >
问题:

使用Tesseract的Android OCR应用程序

景宏富
2023-03-14

我正在学习这个网站上提到的教程:

http://gaut.am/making-an-ocr-android-app-using-tesseract/

并将其链接到我的项目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();

知道它为什么会坠毁吗?

共有1个答案

尚鸿才
2023-03-14

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

 类似资料:
  • 想要一个OCR在android中运行的例子,我做了一些研究,找到了一个在android中实现OCR的例子。 https://github.com/rmtheis/tess-two,里面有三个项目文件... 我已经通过导入三个项目文件执行了“tess-two-test”项目,但是“tess-two-test”不包括任何活动,所以它不会运行。 有谁能一步一步地给我解释这个功能吗

  • 我在Android Studio中使用Tesseract来识别图片中的文本。当我像这样调用以下函数时: 会有一条红线表示“支持库不应该使用与CompilesDKVersion不同的版本”。然后我将compileSdkVersion和targetSdkVersion更改为22,我可以看到错误。 我可以在“compile'com.android.support:design:23.1.1'”下面看到一

  • 我试图理解我们什么时候需要使用这个应用程序。在我们的node Express中使用 当我在网上搜索时,我在reddit上偶然发现了这个答案,它说明了应用程序之间的区别。获取和应用程序。使用 在此基础上,我总结了以下几点。 充当超级路由或中间件?这意味着它在? 此外,如果有人能添加更多关于app.use.的信息/练习,我将不胜感激

  • 我们有一个应用程序,利用在应用程序计费。我们看到的问题如下: 当使用较高版本代码的构建被上传到Play Developer控制台时,In App Billing将停止在设备上的应用程序(使用较低版本代码)上工作,表示“应用程序未配置为计费”。 这很好,在测试的时候,但问题是--当应用程序在Google Play商店中时,会有什么行为?当您替换应用程序(以执行更新)时,处于野生状态(具有较低版本代码

  • 我正试图根据本手册构建一个< code>Tesseract库:使用git-bash(版本 无论我做什么以及它如何失败,原因都是一样的-当涉及到<code>轻量级</code>时,我看到的错误如下: 找不到由“SW”提供的具有以下任何名称的软件包配置文件: SWConfig.cmake sw-config.cmake 我已经将放在PATH指示的位置,但它没有帮助 - 错误仍然存在。存储库中是否可能缺

  • 当我在Tomcat上部署应用程序的战争并启动应用程序时,我收到以下错误。 严重:Servlet[泽西Web应用程序]在Web应用程序[/Reaser-api]抛出的负载()异常java.lang.AbstractMathodError:接收器类org.glassfish.jersey.internal.config.外部属性AutoDiscoverable没有定义或继承的接口org.glassfi