Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
137 views
in Technique[技术] by (71.8m points)

Errors with Tesseract in Android

I am following this tutorial to include tesseract in my android app. Below is my activity code:

package com.MyApp;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import com.googlecode.tesseract.android.TessBaseAPI;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.content.res.AssetManager;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Matrix;
import android.media.ExifInterface;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.provider.MediaStore;
import android.provider.MediaStore.Images.Media;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.TextView;


public class OCRExample extends Activity {
    protected Button _button;
    protected ImageView _image;
    protected TextView _field;
    protected String _path;
    protected boolean _taken;

    protected static final String PHOTO_TAKEN = "photo_taken";
    private static final int TAKE_PHOTO_CODE = 1;
    public static final String PACKAGE_NAME = "com.datumdroid.android.ocr.simple";
    public static final String DATA_PATH = Environment
            .getExternalStorageDirectory().toString() + "/SimpleAndroidOCR/";
    public static final String lang = "eng";

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

    @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");
                }
            }

        }       

        if (!(new File(DATA_PATH + "tessdata/" + lang + ".traineddata")).exists()) {
            try {
                AssetManager assetManager = getAssets();
                InputStream in = assetManager.open("tessdata/eng.traineddata");
                //GZIPInputStream gin = new GZIPInputStream(in);
                OutputStream out = new FileOutputStream(DATA_PATH
                        + "tessdata/eng.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.ocrexample);

        _image = ( ImageView ) findViewById( R.id.image );
        _field = ( TextView ) findViewById( R.id.field );
        _button = ( Button ) findViewById( R.id.button );        
         _path = DATA_PATH + "/ocr.jpg";    
    }

    public void takepic(View v){    
            startCameraActivity();      
    }

    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(OCRExample.PHOTO_TAKEN, _taken);
    }

    @Override
    protected void onRestoreInstanceState(Bundle savedInstanceState) {
        Log.i(TAG, "onRestoreInstanceState()");
        if (savedInstanceState.getBoolean(OCRExample.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();

        _field.setText(recognizedText);     // Cycle done.
    }   
}

I am getting the following errors:

07-17 14:22:49.124: E/AndroidRuntime(15702): FATAL EXCEPTION: main
07-17 14:22:49.124: E/AndroidRuntime(15702): java.lang.ExceptionInInitializerError
07-17 14:22:49.124: E/AndroidRuntime(15702):    at com.MyApp.OCRExample.onPhotoTaken(OCRExample.java:210)
07-17 14:22:49.124: E/AndroidRuntime(15702):    at com.MyApp.OCRExample.onActivityResult(OCRExample.java:134)
07-17 14:22:49.124: E/AndroidRuntime(15702):    at android.app.Activity.dispatchActivityResult(Activity.java:4723)
07-17 14:22:49.124: E/AndroidRuntime(15702):    at android.app.ActivityThread.deliverResults(ActivityThread.java:3175)
07-17 14:22:49.124: E/AndroidRuntime(15702):    at android.app.ActivityThread.handleSendResult(ActivityThread.java:3222)
07-17 14:22:49.124: E/AndroidRuntime(15702):    at android.app.ActivityThread.access$1100(ActivityThread.java:134)
07-17 14:22:49.124: E/AndroidRuntime(15702):    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1263)
07-17 14:22:49.124: E/AndroidRuntime(15702):    at android.os.Handler.dispatchMessage(Handler.java:99)
07-17 14:22:49.124: E/AndroidRuntime(15702):    at android.os.Looper.loop(Looper.java:137)
07-17 14:22:49.124: E/AndroidRuntime(15702):    at android.app.ActivityThread.main(ActivityThread.java:4697)
07-17 14:22:49.124: E/AndroidRuntime(15702):    at java.lang.reflect.Method.invokeNative(Native Method)
07-17 14:22:49.124: E/AndroidRuntime(15702):    at java.lang.reflect.Method.invoke(Method.java:511)
07-17 14:22:49.124: E/AndroidRuntime(15702):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:787)
07-17 14:22:49.124: E/AndroidRuntime(15702):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:554)
07-17 14:22:49.124: E/AndroidRuntime(15702):    at dalvik.system.NativeStart.main(Native Method)
07-17 14:22:49.124: E/AndroidRuntime(15702): Caused by: java.lang.UnsatisfiedLinkError: Couldn't load lept: findLibrary returned null
07-17 14:22:49.124: E/AndroidRuntime(15702):    at java.lang.Runtime.loadLibrary(Runtime.java:365)
07-17 14:22:49.124: E/AndroidRuntime(15702):    at java.lang.System.loadLibrary(System.java:535)
07-17 14:22:49.124: E/AndroidRuntime(15702):    at com.googlecode.tesseract.android.TessBaseAPI.<clinit>(TessBaseAPI.java:47)

What is missing from my project? Line 210 (where the error occurs) in my code is this:

TessBaseAPI baseApi = new TessBaseAPI();
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

The error message states all that you need, the leptonica (specifically liblept.so) is not found, make sure that you have that library available at runtime (check library projects imported correctly)


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...